Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Множення та ділення




Збільшення та зменшення

Іноді у програмі на Асемблері буває потрібно виконати складання, яке складається просто у додатку до операнду значення 1. Така операція зветься збільшенням (інкрементацією). Аналогічно, зі змісту регістрів та змінних у пам’яті іноді потрібно відняти значення 1. Така операція зветься зменшенням (декрементацією). Для таких операцій, як зміна змісту лічильника чи просування регістрів-вказівників по пам’яті чи операнди складання та віднімання можна виконувати за допомогою збільшення чи зменшення. Для виконання таких часто необхідних дій у наборі інструкцій процесорів 8086 передбачені дві інструкції – INC (збільшити) та DEC (зменшити). Інструкція INC додає до регістру чи змінної у пам’яті 1, а інструкція DEC віднімає з регістрів чи змінної 1.

 

Наприклад, наступна програма заповнює 10-байтовий масив TempArray числами 0, 1, 2, 3, 4, 5, 6, 7, 8, 9:

 

TempArray DB 10 DUP (?)

FillCount DW?

 

mov al,0; перше значення,

; записується у TempArray

mov bx,OFFSET TempArray; BX вказує на TempArray

mov [FillCount],10; число елементів якими потрібно

; заповнити масив

FillTempArrayLoop:

mov [bx],al; установити поточний елемент

; TempArray

inc bx; посилка на наступний елемент

; масиву TempArray

inc al; наступне значення, яке

; записується

dec [FillCount]; зменшити лічильник числа

; елементів, які заповнюються

jnz FillTempArray; обробити наступний елемент,

; якщо ми ще не заповнили всі елементи.

Чому переважно використовувати інструкцію:

 

inc bx

 

а не інструкцію:

 

add bx,1

 

вони ж роблять одне й теж? Це так, але в той же час, як інструкція ADD займає 3 байта, інструкція INC займає тільки 1 байт та виконується швидше. Фактично, більш економно виконати дві операції INC, ніж додати до регістра розміром у слово значення 2 (збільшення чи зменшення регістрів та змінних у пам’яті розміром у байт займає 2 байта, що також коротше, ніж складання та віднімання).

Коротше кажучи, інструкції INC та DEC – це найбільш ефективні інструкції, за допомогою яких можна збільшувати та зменшувати значення змінних у пам’яті та регістрів. Їх слід використовувати там, де це можливо.

Процесор 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.




Поделиться с друзьями:


Дата добавления: 2015-04-25; Просмотров: 583; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.