Учебник по ассемблеру (ASM)
 

Ассемблер в примерах - Вычисление выражения

Вопрос:
Найти значение выражения: (a – d)/b + d при a=12; b=17; d=2110 Часть программы в приложении.
.686 	           
.model flat, stdcall 			     
.data 			           
a dw 12;     
b dw 17;     
d dw 2110; 
rez dw ?; 
.code 			                
start:  
mov ax,a				
sub ax,d                                
mov dx,b
ret 				
end start 			
Ответ:
;Найти значение выражения: (a – d)/b + d при a=12; b=17; d=2110
;MASM32

.386 
.model flat, stdcall

.data
a DD 12
b DD 17
d DD 2110

res DD ?

.code

;ВОЗВРАТ: eax = (@@a – @@d)/@@b + @@d
Get_Result PROC USES edx @@a:DWORD, @@b:DWORD, @@d:DWORD

mov eax,@@a
sub eax,@@d ;(@@a – @@d)

cdq ;преобразование двойного слова в учетверенное слово, копирует знаковый бит EAX на все биты EDX
idiv @@b ;/@@b

add eax,@@d ;+ @@d

ret
Get_Result ENDP

start:

push d
push b
push a
call Get_Result ;или invoke Get_Result, a,b,d

mov res,eax ;res:= (12 – 2110)/17 + 2110 = 1987

nop

;...
;выход из программы
;...



END start 
Вот еще вариант более соответствующий masm32 - используются полезные макросы
; (a – d)/b + d при a=12; b=17; d=2110
    .486
    .model flat, stdcall
    option casemap :none   ; case sensitive

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\kernel32.inc
    include \masm32\macros\macros.asm
    include \masm32\include\Fpu.inc

    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\Fpu.lib
    
    .data
a db "12",0    ; текстовая запись чисел
b db "17",0
d db "2110",0

a_real dt 0   ; не обязательно - храним преобразованные в вещественные
b_real dt 0   ; можно было обойтись, но так проще и нагляднее
d_real dt 0

result db 32 dup(0)    ; место для результата
res_title  db "Результат",0  ; заголовок окна

    .code
start:
    invoke FpuAtoFL, ADDR a, ADDR a_real, DEST_MEM      ; преобразовываем строку в вещественное
    invoke FpuAtoFL, ADDR b, ADDR b_real, DEST_MEM
    invoke FpuAtoFL, ADDR d, ADDR d_real, DEST_MEM
    
; вычитаем из преобразованного преобразованные и запоминаем в числовом процессоре
; см. Help -> FPU Lib Help -> Available Functions
; источник1 = вещественное, источник2 = вещественное, результат в сопроцессоре
; 3 параметр поэтому игнорируется
    invoke FpuSub, ADDR a_real, ADDR d_real, 0, SRC1_REAL or SRC2_REAL or DEST_FPU
; Эти аналогчно, но результат предыдущего в сопроцессоре    
    invoke FpuDiv, 0, ADDR b_real, 0, SRC1_FPU or SRC2_REAL or DEST_FPU
    invoke FpuAdd, 0, ADDR d_real, 0, SRC1_FPU or SRC2_REAL or DEST_FPU
; Преобразование результата в сопроцессоре в строку
; первый параметр игнорируется (в сопроцессоре источник), 
; второй - сколько чисел после десятичной точки
; треий - куда сохранить
    invoke FpuFLtoA, 0, 2, ADDR result, SRC1_FPU or SRC2_DIMM

; это тривально, можно было и с print сделать, но тогда нужно будет организовывать задержку
    invoke MessageBox, 0, ADDR result, ADDR res_title, MB_OK
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

end start

   Вперёд
   Содержание