2.3.3.Десятичная арифметика

Процессоры Intel поддерживают операции с двумя форматами десятичных чисел: неупакованное двоично-десятичное число - байт, принимающий значения от 00 до 09h, и упакованное двоично-десятичное число - байт, принимающий значения от 00 до 99L Все обычные арифметические операции над такими числами приво­дят к неправильным результатам. Например, если увеличить 19h на 1, то полу­чится число lAh, а не 20h. Для коррекции результатов арифметических действий над двоично-десятичными числами используются приведенные ниже команды.

Команда

Назначение

Процессор

DAA

BCD-коррекция после сложения

BGB6

Если эта команда выполняется сразу после ADD (ADC, INC или XADD) и в ре­гистре AL находится сумма двух упакованных двоично-десятичных чисел, то в ALзаписывается упакованное двоично-десятичное число, которое должно было стать результатом сложения. Например, если AL содержит число 19h, последова­тельность команд

inc

daa

приведет к тому, что в AL окажется 20h (а не 1 Ah, как было бы после INC).

 

ВАЛ выполняет следующие действия:

1. Если младшие четыре бита АЕ больше 9 или флаг АР = 1,

то АЕ увеличивается на 6, С¥ устанавливается,если при этом сложении произошел перенос, и АЕустанавливается в 1.

2. Иначе АР = 0.

3. Если теперь старшие четыре бита АЕ больше 9 или флаг СЕ= 1, то АЕ увеличивается на 60к и СЕустанавливается в 1.

4. Иначе СЕ = 0.

Флаги АБ и СБ устанавливаются, если в ходе коррекции происходил перенос из первой или второй цифры. ББ, 7Б и РБ устанавливаются в соответствии с ре­зультатом, флаг ОБ не определен.

Команда

Назначение

Процессор

DAS

BCD-коррекция после вычитания

BGB6

Если эта команда выполняется сразу после SUB (SBB или DEC) и в регистре AL находится разность двухупакованныхдвоично-десятичныхчисел, то в AL записыва-етсяупакованноедвоично-десятичноечисло,котороедолжнобылобытьрезультатом вычитания. Например, если AL содержит число 20h, последовательность команд

dec al das

приведет к тому, что в регистре окажется 19h (а не lFh, как было бы после DEC).

 

DAS выполняет следующие действия:

1. Если младшие четыре бита AL больше 9 или флаг АЕ = 1,

то AL уменьшается на 6, CF устанавливается, если при этом вычита­нии произошел заем, и АР устанавливается в 1. .

2. ИначеА¥= 0.

3. Если теперь старшие четыре бита AL больше 9 или флаг СЕ- 1, то AL уменьшается на 60h и СЕустанавливается в 1.

4. Иначе СЕ= 0.

Известный пример необычного использования этой команды ~ самый ком­пактный вариант преобразования шестнадцатеричной цифры в ASCII-код соответствующего символа (более длинный и очевидный вариант этого преобразования рассматривался в описании команды XLAT):

стр al,10

sbb al,69h

das

После числа 0-9 превращаются в 96h - 9Fh, а числа - -в 0A1h - 0A6h. Затем DAS вычитает 66h из первой группы чисел, переводя их в 30h - 39h, и 60h из второй группы чисел, переводя их в 41h - 46h.

Флаги AF и CF устанавливаются, если в ходе коррекции происходил заем из первой или второй цифры. SF, ZF и PF устанавливаются в соответствии с резуль­татом, флаг OF не определен.

Команда

Назначение

Процессор

ААА

ASCII-коррекция после сложения

BGB6

Корректирует сумму двух неупакованных двоично-десятичных чисел в АЬ. Если коррекция приводит к десятичному переносу, АН увеличивается на 1. Эту команду лучше использовать сразу после команды сложения двух таких чисел. Например, если при сложении 05 и 06 в АХ окажется число ОООВп, то команда ААА скорректирует его в 0101Ь (неупакованное десятичное 11). Флаги СБ и ОБ устанавливаются в 1, если произошел перенос из АЬ в АН, в противном случае они равны нулю. Значения флагов ОБ, ББ, 7Б и РБ не определены.

Команда

Назначение

Процессор

AAS

ASCII-коррекция после вычитания

BGB6

Корректирует разность двух неупакованных двоично-десятичных чисел в АЬ сразу после команды БИВ или БВВ. Если операция приводит к займу, АН уменьша­ется на 1. Флаги СЬ и ОЬ устанавливаются в 1, если произошел заем из АЬ в АН, и в ноль - в противном случае. Значения флагов ОБ, ББ, 7Б и РБ не определены.

Команда

Назначение

Процессор

ДАМ

ASCII-коррекция после умножения

BGB6

Корректирует результат умножения неупакованных двоично-десятичных чисел, который находится в АХ после выполнения команды МиЬ, преобразовывая полу­ченное в пару неупакованных двоично-десятичных чисел (в АН и АЬ). Например:

mov al,5

mov Ы, 5

mul Ы aam

Умножить 5 на 5.

Результат в АХ - 0019h. Теперь АХ содержит G2G5h.

ААМ устанавливает флаги БЬ, 7Ь и РЬ в соответствии с результатом и остав­ляет ОЬ, АЬ и СЬ неопределенными.

 

Код команды ААМ - D4h OAh, где OAh - основание системы счисления, по отношению к которой выполняется коррекция. Этот байт можно заме­нить на любое другое число (кроме нуля), и ААМ преобразует АХ к двум не­упакованным цифрам любой системы счисления. Такая обобщенная форма ААМработает на всех процессорах (начиная с 8086), но появляется в доку­ментации Intel только с процессоров Pentium. Фактически действие, кото­рое выполняет ААМ, - целочисленное деление AL на OAh (или любое другое Непривилегированные  команды ІІМвШИКЛ число в общем случае), частное помещается в АН, и остаток - в ЛЬ, поэто­му команду часто используют для быстрого деления в высокооптимизиро-ванных алгоритмах.

Команда

Назначение

Процессор

AAD

ASCII-коррекция перед делением

вове

Выполняет коррекцию неупакованного двоично-десятичного числа, находяще­гося в регистре АХ, так, чтобы последующее деление привело к десятичному ре­зультату. Например, разделим десятичное 25 на 5:

шоу ах,0205п ; 25 в неупакованном формате,

шоу Ы,5

аасі ; Теперь в АХ находится 19п.

сііл/ Ы ; АХ = 0005.

Флаги SF, ZF и PF устанавливаются в соответствии с результатом, OF, AF и CF не определены.

/~Ч Команда ААЬ), как и ААМ, используется с любой системой счисления: ее код -\Щй В5к ОАк, и второй байт можно заменить на любое другое число. Действие ААГ) заключается в том, что содержимое регистра АН умножается на второй байт команды (ОАп по умолчанию) и складывается с АЬ, после чего АН обнуляется, так что ААЬ) можно использовать для быстрого умноже­ния на любое число.