Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 179

Unknown Author

(decimal adjust after addition): DAA

Эта команда имеет смысл, только если она поставлена после команды сложения, которая сложила упакованную пару правильных десятичных цифр и записала сумму в регистр AL. Команда DAA преобразует значение этого регистра в две правильные десятичные цифры и фиксирует в флаге CF перенос из этих цифр. Например:

MOV AL,59h

ADD AL,69h    ;AL=0C2h

DAA    ;CF=1, AL=28h

Более точно команда DAA действует так: если AF=1 или если величина в 4 правых битах AL больше 9, тогда AL увеличивается на 6 (это коррекция правой цифры пары); если CF=1 или если величина в 4 левых битах AL больше 9, то к AL прибавляется число 60h ( т. е. 6 к левой половине) и CF получает значение 1, а иначе CF получает значение 0 (это коррекция левой цифры и учет переноса из данной пары цифр). Команда меняет и другие флаги, но их значения обычно не представляют интерес.

Например, в приведенных выше командах сумма правых цифр (9 и 9) равна 18 = 12h, поэтому в правую половину регистра AL попадает цифра 2, а цифра 1 как перенос добавляется к сумме левых цифр (5+6+1=12=0Ch), при этом флаг AF получает значение 1. По этому значению AF команда DAA и узнает, что правая цифра в AL неправильная, и увеличивает ее на 6; в этот момент AL=0C8h. Далее анализируется левая половина регистра AL: поскольку в команде ADD не было переноса, то CF=0, но в левых битах AL находится величина ОСЬ, которая больше 9, поэтому левую цифру также надо скорректировать, для чего к ней прибавляется 6 (с записью переноса в CF): (12+6) mod 16 = 2 и CF=1.

Для примера приведем алгоритм сложения описанных выше чисел X, Y и Z, когда их значения трактуются как 2*К-значные упакованные числа:

;сложение упакованных 2-10-ных чисел: Z:=X+Y

MOV CX,N    количество байтов (пар цифр) в слагаемых

;индекс байта слагаемых (справа налево)

MOV SI,N-1 CLC

SUM: MOV AL,X[SI] ADC AL,Y[SI] DAA

MOV Z[SI+1],AL DEC SI LOOP SUM MOV Z,0 ADC Z,0

;CF - перенос из младших цифр (вначале его нет)

;сложение двух пар цифр с учетом переноса ;коррекция цифр суммы и запись в CF переноса ;запись пары цифры суммы в Z ;(команды DEC и LOOP ; ие меняют флаг CF)

;запись в Z переноса из старших цифр

14.13. Вычитание двоично-десятичных чисел

Здесь все аналогично сложению. Вычитание двоично-десятичных чисел также осуществляется по цифрам, от младших цифр к старшим. Для коррекции же разности цифр в ПК используются команды AAS и DAS.

ASCII-коррекция после вычитания (ASCII adjust after subtraction): AAS

Эту команду следует применять после команды вычитания (SUB и т. п.), которая записывает разность двух десятичных цифр в регистр AL. Команда AAS действует так: если AF=1 или если величина 4 правых битов AL больше 9, тогда из AL вычитается 6, из АН вычитается 1 и флаг CF получает значение 1 (фиксируется заем из старших цифр), иначе же флаг CF получает значение 0; в любом случае обнуляются 4 левых бита регистра AL. Например:

;коррекция ие нужна MOV AL,05h

SUB AL,02h    ;AL=03h, AF=0

AAS    ;AL=03h, CF=0

;коррекция нужна MOV AL,02h

SUB AL,05h    ;AL=0FDh, AF=1