КАТЕГОРИИ: Архитектура-(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; Просмотров: 606; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |