Читать «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.1
Здесь все аналогично сложению. Вычитание двоично-десятичных чисел также осуществляется по цифрам, от младших цифр к старшим. Для коррекции же разности цифр в ПК используются команды 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