- •Тема 2. Архітектура процесора і мова асемблера: Основи програмування на мові асемблера
- •4.1. Арифметичні дії над неупакованими bcd-числами
- •4.1.1. Додавання неупакованих bcd-чисел
- •4.1.2. Віднімання неупакованих bcd-чисел
- •4.1.3. Множення неупакованих bcd-чисел
- •4.1.4. Ділення неупакованих bcd-чисел
- •4.2. Арифметичні дії над упакованими bcd-числами
- •4.2.1. Додавання упакованих bcd-чисел
- •4.2.2. Віднімання упакованих bcd-чисел
4.1. Арифметичні дії над неупакованими bcd-числами
4.1.1. Додавання неупакованих bcd-чисел
Розглянемо два випадки додавання.
Приклад
9. Результат
додавання
не більше
9
6
= 0000 0110
+
3
= 0000 0011 9
= 0000 1001
Перенесення з молодшої тетради в старшу немає. Результат правильний.
Т
Приклад
10. Результат
додавання
більше 9
06
= 0000 0110
+
07
= 0000 0111 13
= 0000 1101
0000 0001 0000 0011 в двійковому поданні (або 13 в десятковому).
Проаналізувавши дану проблему при додаванні BCD-чисел (і подібні проблеми при виконанні інших арифметичних дій) та можливі шляхи її вирішення, розробники системи команд мікропроцесора вирішили не вводити спеціальні команди для роботи з BCD-числами, а ввести декілька коректуючих команд.
Призначення цих команд - в коректуванні результату роботи звичайних арифметичних команд для випадків, коли операнди в них є BCD-числами.
У разі додавання у прикладі 10 видно, що отриманий результат потрібно коректувати. Для корекції операції додавання двох однозначних неупакованих BCD-чисел в системі команд мікропроцесора існує спеціальна команда
aaa (ASCII Adjust for Addition) — корекція результату додавання для подання в символьному вигляді.
Ця команда не має операндів. Вона працює неявно тільки з регістром al і аналізує значення його молодшої тетради:
• якщо це значення менше 9, то прапор cf скидається в 0 і здійснюється перехід до наступної команді;
• якщо це значення більше 9, то виконуються наступні дії:
- до вмісту молодшої тетради al (але не до вмісту всього регістру!) додається 6, тим самим значення десяткового результату коректується в правильний бік;
- прапор cf встановлюється в 1, тим самим фіксується перенесення в старший розряд, для того щоб його можна було врахувати в подальших діях.
Лістинг 6. Додавання неупакованих BCD-чисел <1> ;prg_10_2.asm <2> ... <3> .data <4> len equ 2 ; розрядність числа <5> b db 1,7 ; неупаковане число 71 <6> c db 4,5 ; неупаковане число 54 <7> sum db 3 dup (0) <8> .code <9> main: ;точка входу в програму <10> ... <11> xor bx,bx <12> mov cx,len <13> m1: <14> mov al,b[bx] <15> adс al,c[bx] <16> aaa <17> mov sum[bx],al <18> inc bx <19> loop m1 <20> adc sum[bx],0 <21> ... <22> exit:
|
У лістингу 6 є декілька цікавих моментів, над якими є сенс подумати. Почнемо з опису BCD-чисел. З рядків 5 і 6 видно, що порядок їх введення зворотний нормальному, тобто цифри молодших розрядів розташовані за меншою адресою. Але це цілком логічно з кількох причин:
• по-перше, такий порядок відповідає загальному принципу представлення даних для мікропроцесорів Intel;
• по-друге, це дуже зручно для порозрядної обробки неупакованих BCD-чисел, оскільки кожна з них займає один байт.
Хоча, як вже було зазначено, програміст вільний сам вибирати спосіб опису BCD-чисел в сегменті даних. Рядки 14-15 містять команди, які додають цифри в чергових розрядах BCD-чисел, при цьому враховується можливе перенесення з молодшого розряду. Команда aaa в рядку 16 коректує результат додавання, формуючи в al BCD-цифру і, при необхідності, встановлюючи в 1 прапор cf. Рядок 20 враховує можливість перенесення при додаванні цифр з самих старших розрядів чисел. Результат додавання формується в полі sum, описаному в рядку 7.