Команды DIV и IDIV

Команды MUL и IMUL

Команда MUL может быть записана в трех различных форматах — в зависимости от операнда:

MUL r/m8 MUL r/ml6 MUL r/m32

В 8-разрядной форме операнд может быть любым 8-битным регистром или адресом памяти. Второй операнд всегда хранится в AL. Результат (произведение) будет записан в регистр АХ.

(r/m8)*AL -> АХ

В 16-разрядной форме операнд может быть любым 16-битным регистром или адресом памяти. Второй операнд всегда хранится в АХ. Результат сохраняется в паре DX:AX.

(r/ml6)*АХ -> DX:AX

В 32-разрядной форме второй операнд находится в регистре ЕАХ, а результат записывается в пару EDX.EAX.

(r/m32)*ЕАХ -> EDX:ЕАХ

Пример 1: умножить значения, сохраненные в регистрах ВН и CL, результат сохранить в регистр АХ:

mov al,bh; AL = ВН — сначала заносим в AL второй операнд

mul cl; АХ = AL*CL — умножаем его на CL

Результат будет сохранен в регистре АХ.

Пример: вычислить 4862, результат сохранить в DX:AX:

mov ax,486; АХ = 486

mul ах; АХ*АХ —> DX:AX

Пример 2: вычислить диаметр по радиусу, сохраненному в 8-битной переменной radius l, результат записать в 16-битную переменную diameterl:

mov al,2; AL = 2

mul byte [radiusl]; AX = radius * 2

mov [diameterl],ax; diameter <— AX

Почему результат 16-разрядного умножения сохранен в паре DX:AX, а не в каком-то 32-разрядном регистре? Причина — совместимость с предыдущими 16-разрядными процессорами, у которых не было 32-разрядных регистров.

Команда IMUL умножает целые числа со знаком и может использовать один, два или три операнда. Когда указан один операнд, то поведение IMUL будет таким же, как и команды MUL, просто она будет работать с числами со знаком.

Если указано два операнда, то инструкция IMUL умножит первый операнд на второй и сохранит результат в первом операнде, поэтому первый операнд всегда должен быть регистром. Второй операнд может быть регистром, непосредственным значением или адресом памяти.

imul edx,ecx; EDX = EDX*ECX

imul ebx,[sthing]; умножает 32-разрядную

; переменную "sthing" на ЕВХ,

; результат будет сохранен в ЕВХ

imul есх,6; ЕСХ = ЕСХ*6

Если указано три операнда, то команда IMUL перемножит второй и третий операнды, а результат сохранит в первый операнд. Первый операнд — только регистр, второй может быть любого типа, а третий должен быть только непосредственным значением:

imul edx,ecx,7; EDX = ECX*7

imul ebx,[sthing],9; умножаем переменную "sthing" на 9,

; результат будет сохранен EBX

imul ecx,edx,ll; ЕСХ = EDX*11

Подобно команде MUL, команда DIV может быть представлена в трех различных форматах в зависимости от типа операнда (операнд служит делителем, а делимое находится в фиксированном месте):

DIV r/m8 DIV r/ml6 DIV r/m32

В 8-битной форме переменный операнд (делитель) может быть любым 8-битным регистром или адресом памяти. Делимое содержится в АХ. Результат сохраняется так: частное — в AL, остаток — в АН.

АХ/(r/m8) —> AL, остаток —> АН

В 16-битной форме операнд может быть любым 16-битным регистром или адресом памяти. Второй операнд всегда находится в паре DX:AX. Результат сохраняется в паре DX:AX (DX — остаток, АХ — частное).

DX:AX/(r/ml6) —> АХ, остаток —> DX

В 32-разрядной форме делимое находится в паре EDX:EAX, а результат записывается в пару EDX:EAX (частное в ЕАХ, остаток в EDX).

EDX:EAX/(r/m32) —> ЕАХ, остаток —> EDX

Команда IDIV используется для деления чисел со знаком, синтаксис ее такой же, как у команды DIV.

Пример 1: разделить 13 на 2, частное сохранить в BL, а остаток в — ВН:

mov ах,13; АХ = 13

mov cl,2; CL = 2

div cl; делим на CL

mov bx,ax; ожидаемый результат находится

; в АХ, копируем в ВХ

Пример 2: вычислить радиус по диаметру, значение которого сохранено в 16-битной переменной diameter1, результат записать в radius1, а остаток проигнорировать.

mov ax,[diameter1]; AX = diameter1

mov bl,2; загружаем делитель 2

div bl; делим

mov [radiusl],al; сохраняем результат


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: