9.3. Операции над упакованными десятичными числами

Для арифметических операций над числами, представленными в формате 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