Для арифметических операций над числами, представленными в формате BCD, (Binary Coded Decimal) определены команды:
daa — десятичная коррекция AL после сложения,
das — десятичная коррекция AL после вычитания.
Команда daa применяется после сложения упакованных чисел, каждое из которых состоит из двух цифр, записанных в две тетрады. Сначала корректируется младшая тетрада. Если ее содержимое больше 9, то к ней прибавляется 6 и к старшей тетраде прибавляется 1. После этого корректируется старшая тетрада, аналогичным образом: если ее содержимое больше 9, то прибавляется 6 и устанавливается флаг CF. При сложении младших тетрад может сформироваться неверная цифра, например, после 9 + 9 = 18 в младшую тетраду будет записана цифра 2. В этом случае в AF записывается 1. Команда коррекции увеличивает на 6 содержимое младшей тетрады, если AF=1 или содержимое младшей тетрады больше 9.
Аналогично действует команда das коррекции при вычитании. Если AF=1 или младшая тетрада AL больше 9, то она вычитает из AL число 6. Затем обрабатывается старший разряд: если CF=1 или AL больше 9Fh, то AL = AL – 60h.
Пример. Напишем программу вычитания двух чисел, определенных как
a dt 98765432109876543210,
b dt 1234565432102345678.
Воспользуемся командой коррекции:
< 1 > title das.exe
< 2 > code segment
< 3 > assume cs:code, ds:code, es:code
< 4 > extrn display:near
< 5 > main proc far
< 6 > push es
< 7 > mov ax,0
< 8 > push ax
< 9 > mov bx,code
< 10 > mov ds,bx
< 11 > mov es,bx
< 12 > ;——вычитание BCD — чисел————
< 13 > mov ax,0
< 14 > push ax
< 15 > popf ;очистить все флаги
< 16 > cld ;прямое направление
< 17 > lea si,a
< 18 > lea bx,b
< 19 > lea di,res ;результат
< 20 > mov cx,10 ;10 цифр
< 21 > next:
< 22 > lodsb ;[ds:si++]->al
< 23 > sbb al,[bx] ;вычитание
< 24 > das ;коррекция
< 25 > stosb ;al->es:di++
< 26 > inc bx
< 27 > loop next
< 28 > ;——вывод результата——————
< 29 > lea si,res+9
< 30 > mov cx,10
< 31 > std ;обратное направление
< 32 > again:
< 33 > lodsb ;[ds:si—]->al
< 34 > mov dl,al
< 35 > call hex
< 36 > loop again
< 37 > ret
< 38 > a dt 98765432109876543210
< 39 > b dt 1234565432102345678
< 40 > res dt 0
< 41 > main endp
< 42 > hex proc near
< 43 > mov ax,cs
< 44 > push ds
< 45 > mov ds, ax ; set ds=cs
push dx
< 1 >
< 2 > mov bx, offset table
< 3 > mov al, dl
< 4 > clc
< 5 > shr al,1
< 6 > shr al,1
< 7 > shr al,1
< 8 > shr al,1
< 9 > xlatb ; translate
< 10 > mov dl, al
< 11 > call display
< 12 > pop ax
< 13 > and al, 00001111b
< 14 > xlatb ; translate
< 15 > mov dl, al
< 16 > call display
< 17 > pop ds
< 18 > ret
< 19 > table db ‘0123456789ABCDEF’
< 20 > hex endp
< 21 > code ends
< 22 > end main