Множення та ділення
Процесор 8086 може виконувати окремі типи операцій множення та ділення, Це одна з сильних сторін процесору 8086, тому що в багатьох мікропроцесорах взагалі відсутня безпосередня підтримка операції множення та ділення, а ці операції досить складно виконати програмним шляхом. Інструкція MUL перемножує 8- чи 16- бітові беззнакові співмножники, створюючи 16- чи 32-бітовий добуток. Давайте спочатку роздивимось множення 8-бітових співмножників. При 8-бітному (8-розрядному) множенні один з операндів повинен зберігатися у регістрі AL, а інший може являти собою будь-який 8-бітовий загальний регістр чи змінну пам’яті відповідного розміру. Інструкція MUL завжди зберігає 16-бітовий добуток у регістрі AX. Наприклад, в фрагменту програми:
mov al,25 mov dh,40 mul dh
AL множиться на DH, а результат (1000) розміщується у регістрі AX. Зауважимо, що в інструкції MUL потрібно указувати тільки один операнд, другий співмножник завжди зберігається у регістрі AL (чи в регістрі AX у випадку перемноження 16-бітових множників). Інструкція перемноження 16-бітових співмножників працює аналогічно. Один зі співмножників повинен зберігатися у регістрі AX, а другий може знаходитися у 16-розрядному загальному регістрі чи у змінній пам’яті. 32-бітовий добуток інструкція MUL розміщує в цьому випадку в регістрі DX:AX, при цьому молодші (менш значущі) 16 бітів додатку записуються у регістр AX, а старші (більш значущі) 16 біт – у регістр DX. Наприклад, інструкції:
mov ax,1000 mul ax
завантажують у регістр AX 1000, а потім підносять його у квадрат, розміщуючи результат (значення 1000000) у регістри DX:AX. На відміну від складання та віднімання, у операції множення не враховується, чи являються співмножники операндами зі знаком чи без знака, тому є друга інструкція множення IMUL для множення 8-ми та 16-бітових співмножників зі знаком. Якщо не приймати до уваги, що перемножуються значення зі знаком, інструкція IMUL працює аналогічно інструкції MUL. Наприклад, при виконанні інструкцій:
mov al,-2 mov ah,10 imul ah у регістрі АХ буде записано значення –20. Процесор 8086 дозволяє нам з певними обмеженнями розділити 32-бітове значення на 16-бітове, чи 16-бітове значення на 8-ми бітове. Давайте спочатку розглянемо ділення 16-бітового значення на 8-ми бітове. При беззнаковому діленні 16-бітового значення на 8-ми бітове ділене повинно бути записано у регістр AX. 8-ми бітовий дільник може зберігатися у любому 8-бітовому загальному регістрі чи змінній у пам’яті відповідного розміру. Інструкція DIV завжди записує 8-бітову частину у регістр AL, а 8-бітовий залишок – в AH. Наприклад, в результаті виконання інструкцій:
mov ax,51 mov dl,10 div dl
результат 5 (51/10) буде записаний у регістр AL, а залишок 1 (залишок від ділення 51/10) – у регістр AH.
Зауважимо, що частка являє собою 8-бітове значення. Це означає, що результат ділення 16-бітового операнда на 8-бітовий операнд повинен перевищити 255. Якщо частка занадто велика, то генерується переривання 0 (переривання по діленню на 0). Інструкціїї:
mov ax,0fffh mov bl,1 div bl
генерують переривання по діленню на 0 (як можна очікувати, переривання по діленню на 0 генерується також, якщо 0 використовується в якості дільника).
При діленні 32-бітового операнда на 16-бітовий операнд ділимо повинно записуватися у регістрах DX:AX. 16-бітовий дільник може знаходитися у будь-якому з 16-бітових регістрів загального призначення чи у змінній пам’яті відповідного розміру. Наприклад, у результаті виконання інструкцій: mov ax,2 mov dx,1; загрузити у DX:AX 10002h mov bx,10h div bx
вчасне 1000h (результат ділення 100002h на 10h) буде записано у регістрі AX, а 2 (залишок від ділення) у регістрі DX. Як при множенні, при діленні має значення, використовуються операнди зі знаком чи без знака. Для ділення беззнакових операндів використовується операція DIV, а для ділення операндів зі знаком –IDIV. Наприклад, операції:
TestDivisor DW 100
mov ax,-667 cwd; встановити DX:AX у значення –667 idiv [TestDivisor]
зберігають значення –6 у регістрі AX і значення –67 у регістрі DX.
|