Специальные команды
Так как делимое всегда должно быть расположено в фиксированных регистрах, которые зависят от его длины, команды расширения делимого не имеют операндов. Код команды расширения определяется тем, что и во что преобразовывается. Команды для подготовки деления заданы в табл. 5.2
Таблица 5.2 Команды для подготовки деления
Выполняемое преобразование | Код | Исходное данное | Результат | ||||
Байт в слово | CBW | AL | AX | ||||
Слово в двойное слово | CWD | AX | DX, AX | ||||
двойное слово в два двойных слова | CDQ | EAX | EDX, EAX | ||||
Слово в двойное слово | CWDE | AX | EAX |
Пример использования арифметических команд.
Пример 5.1 Пусть заданы значения X, Y. Выполнить операции +, - , *, / и вычисления остатка для данных типа DWORD
ideal
p586
model flat
extrn ExitProcess:proc
dataseg
x dd 7fffffffh
y dd 7fffffffh
z dd ?
zl dd ?
zh dd ?
codeseg
begin:
; z=x+y
mov eax, [x]
add eax, [y]
mov [z], eax
; z=y+x
mov eax, [x]
mov ebx, [y]
xadd eax, ebx
mov [z], eax
; z=x-y
mov eax, [x]
sub eax, [y]
mov [z], eax
; z=x*y (x, y - unsigned)
mov eax, [x]
mul [y]
mov [zl], eax
mov [zh], edx
; z=x*y (x, y -int)
mov ebx, [x]
imul ebx, [y]
mov [zl], ebx
; z=x*5 (1 способ)
mov ebx, [x]
imul ebx, 5;
mov [zl], ebx
; z=x*5 (1 способ)
mov ebx, [x]
imul eax, ebx, 5
mov [zl], eax
;zl=x/y; zh=x%y; x, y - unsigned
mov eax, [x]
sub edx, edx
div [y]
mov [zl], eax
mov [zh], edx
;zl=x/y; zh=x%y; x, y -int
mov eax, [x]
cdq
idiv [y]
mov [zl], eax
mov [zh], edx
call ExitProcess
end begin
Для обеспечения максимально быстрого выполнения умножения на целое число используется макрос FASTIMUL, в котором умножение заменяется операциями сложения и сдвига, например, умножение на 5 рассматривается как умножение на 4 (сдвиг на 2 бита влево и сложение первоначального значения). Требуемые операции сдвига и сложения формирует компилятор по сомножителю. Общий вид макрокоманды:
FASTIMUL оп1, оп2, константа; оп2 * константа® оп1