[ЭКЗАМЕН 23] Команды десятичной арифметики. - mRrvz/bmstu-asm GitHub Wiki

Десятичная арифметика DAA, DAS, AAA, AAS, AAM, AAD

Это ваще жесть какая-то...

Упакованный BCD-формат - это упакованное двоично-десятичное число - байт от 00h до 99h (цифры A..F не задействуются).

DAA

Команда DAA (Decimal Adjust AL after Addition) позволяет получать результат сложения упакованных двоично-десятичных данных в таком же упакованном BCD-формате. То есть она корректирует после сложения, пример:

mov AL,71H   ; AL = 0x71h
add AL,44H   ; AL = 0x71h + 0x44h = 0xB5h
daa          ; AL = 0x15h
             ; CF = 1 - перенос является частью результата 71 + 44 = 115

DAS

Команда DAS (Decimal Adjust AL after Subtraction) позволяет получать результат вычитания упакованных двоично-десятичных данных в таком же упакованном BCD-формате. То есть она корректирует после вычитания, пример:

mov AL,71H   ; AL = 0x71h
sub AL,44H   ; AL = 0x71h - 0x44h = 0x2Dh
das          ; AL = 0x27h
             ; CF = 0 - заем (перенос) является частью результата

ASCII-формат - это неупакованное двоично-десятичное число (байт от 00h до 09h).

AAA

Команда AAA (ASCII Adjust After Addition) позволяет преобразовать результат сложения двоично-десятичных данных в ASCII-формат. Для этого команда AAA должна выполняться после команды двоичного сложения ADD, которая помещает однобайтный результат в регистр AL. Если будет перенос, он запишется в AH.

Для того, чтобы преобразовать содержимое регистра AL к ASCII-формату, необходимо после команды AAA выполнить команду OR AL,0x30h (то есть сделать читаемым числом). Пример...:

sub AH,AH    ; очистка AH
mov AL,'6'   ; AL = 0x36h
add AL,'8'   ; AL = 0x36h + 0x38h = 0x6Eh 
aaa          ; AX = 0x0104h 
or AL,30H    ; AL = 0x34h = '4'

AAS

Команда AAS (ASCII Adjust After Subtraction) позволяет преобразовать результат вычитания двоично-десятичных данных в ASCII-формат. Для этого команда AAS должна выполняться после команды двоичного вычитания SUB, которая помещает однобайтный результат в регистр AL. Если был заем, будет вычитание 1 из AH.

Для того, чтобы преобразовать содержимое регистра AL к ASCII-формату, необходимо после команды AAS выполнить команду OR AL,0x30h (то есть сделать читаемым числом).

При положительном результате вычитания это выглядит следующим образом:

sub AH,AH    ; очистка AH
mov AL,'9'   ; AL = 0x39h 
sub AL,'3'   ; AL = 0x39h - 0x33h = 0x06h 
aas          ; AX = 0x0006h 
or AL,30H    ; AL = 0x36h = '6'

при вычитании с получением результа меньше нуля:

sub AH,AH    ; очистка AH
mov AL,'3'   ; AL = 0x33h 
sub AL,'9'   ; AL = 0x33h - 0x39h = 0xFAh 
aas          ; AX = 0xFF04h 
or AL,30H    ; AL = 0x34h = '4' (хз почему)

AAM

AAM imm8 (imm8 - система счисления aka ib ? вроде )

Команда AAM (ASCII Adjust AX After Multiply) позволяет преобразовать результат умножения неупакованных двоично-десятичных данных в ASCII-формат. Для этого команда AAM должна выполняться после команды беззнакового умножения MUL (но не после команды умножения со знаком IMUL), которая помещает двухбайтный результат в регистр AX.

Команда AAM распаковывает результат умножения, содержащийся в регистре AL, деля его на второй байт кода операции ib (равный 0x0Ah для безоперандной мнемоники AAM). Частное от деления (наиболее значащая цифра результата) помещается в регистр AH, а остаток (наименее значащая цифра результата) — в регистр AL .

Для того, чтобы преобразовать содержимое регистра AX к ASCII-формату, необходимо после команды AAM выполнить команду OR AX,0x3030h. Пример:

mov AL,3     ; множимое в формате неупакованного BCD помещается в регистр AL
mov BL,9     ; множитель в формате неупакованного BCD помещается в регистр BL
mul BL       ; AX = 0x03 * 0x09 = 0x001Bh
aam          ; AX = 0x0207h
or AX,3030H  ; AX = 0x3237h, т.е. AH = '2', AL = '7'

AAD

AAD imm8

Команда AAD (ASCII Adjust AX Before Division) используется для подготовки двух разрядов неупакованных BCD-цифр (наименее значащая цифра в регистре AL, наиболее значащая цифра в регистре AH) для операции деления DIV, которая возвращает неупакованный BCD-результат.

Команда AAD устанавливает регистр AL в значение AL = AL + (imm8 * AH) , где imm8 – это второй байт кода операции ib (равный 0x0Ah для безоперандной мнемоники AAD), с последующей очисткой регистра AH. После команды AAD регистр AX будет равен двоичному эквиваленту оригинального неупакованного двухзначного числа.

Пример:

mov AX,0207H   ; делимое в формате неупакованного BCD помещается в регистр AX
mov BL,05H     ; делитель в формате неупакованного BCD помещается в регистр BL
aad            ; AX = 0x001Bh
div BL         ; AX = 0x0205h
or AL,30H      ; AL = 0x35h = '5'

Следующий вопрос: Команды сдвига.

Предыдущий вопрос: Команда LEA.