Last modified: Thu Jun 18 16:56:42 UTC+0200 2026 © A. Tarpai
Decimal stuff: AAM
8086 introduced unpacked (ASCII) BCD along with AAM/AAD. All these instructions are invalid in 64-bit mode.
AAM
Originally made for 10-base unpacked ASCII adjustment after multiply.
F. ex. multiplying 9 x 9 = 81, AL contains 51h. AAM makes 2 x 10-base digits from AL into AH/AL:
AH AL AH AL +----+----+ +----+----+ | xx | 51 | ---- AAM ----> | 08 | 01 | +----+----+ (D4 0A) +----+----+
But the exact operation is an unsigned divide, with the 8-bit DIVISOR following the opcode. It works with any other imm8 value (except that zero makes exception). AH gets the QUOTIENT, AL the REMAINDER.
Compared to insigned DIV:
DIV r/m8 AAM imm8
+-----------+ +----+
| WORD | AX |BYTE| AL
+-----------+ +----+
+----+ +----+
|BYTE| R/M |BYTE| imm8
+----+ +----+
_______________________________ _______________________________
+----+ +----+
|BYTE| AL=QUOTIENT |BYTE| AL=REMAINDER!
+----+ +----+
+----+ +----+
|BYTE| AH=REMAINDER |BYTE| AH=QUOTIENT!
+----+ +----+
NB:
- Opposite results from DIV in AL/AH
- Divident is AL part only
- This is unsigned division, f. ex. 255 by 128 (80h) → AH=1, AL=127. As if old-school div with sub until overflows.
AAD
Originally made for 10-base ASCII adjustment before divide.
F. ex. lets say we have a 2-digit unpacked decimal number in AX as 35 and we try to divide by 7. Before executing DIV, AAD can convert this number to its binary value in AL:
AH AL AH AL +----+----+ +----+----+ | 03 | 05 | ---- AAD ----> | 00 | 23 | 23H = 35 +----+----+ (D5 0A) +----+----+
But the exact operation is an unsigned multiple, with the 8-bit multiplier following the opcode. It works with any other imm8 value. AH is zeroed out (so AX is ready to divide), while AL = AH * imm8 + AL.
Equivalent to this pseudo-code (CPU cannot multiply AH only):
AAD i8 = MUL AH, i8 ADD AL, AH XOR AH, AH
Some usage of AAM and AAD
These can be actually handy, when crunching bits.
AAM 2n
AAM can separate an 8-bit value in AL into higher- and lower n-bits into AH/AL, leaving zero in all other bits.
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
_______________________________ _______________________________
| . | . | . | . | . | . | . | . | |_7_|_6_|_5_|_4_|_3_|_2_|_1_|_0_|
AH AL
_______________________________ _______________________________
| 0 0 0 0 0 0 0 |_7_| | 0 |_6_|_5_|_4_|_3_|_2_|_1_|_0_| AAM 128 AAM 0x80
_______________________________ _______________________________
| 0 0 0 0 0 0 |_7_|_6_| | 0 0 |_5_|_4_|_3_|_2_|_1_|_0_| AAM 64 AAM 0x40
_______________________________ _______________________________
| 0 0 0 0 0 |_7_|_6_|_5_| | 0 0 0 |_4_|_3_|_2_|_1_|_0_| AAM 32 AAM 0x20
_______________________________ _______________________________
| 0 0 0 0 |_7_|_6_|_5_|_4_| | 0 0 0 0 |_3_|_2_|_1_|_0_| AAM 16 AAM 0x10
_______________________________ _______________________________
| 0 0 0 |_7_|_6_|_5_|_4_|_3_| | 0 0 0 0 0 |_2_|_1_|_0_| AAM 8 AAM 0x08
_______________________________ _______________________________
| 0 0 |_7_|_6_|_5_|_4_|_3_|_2_| | 0 0 0 0 0 0 |_1_|_0_| AAM 4 AAM 0x04
_______________________________ _______________________________
| 0 |_7_|_6_|_5_|_4_|_3_|_2_|_1_| | 0 0 0 0 0 0 0 |_0_| AAM 2 AAM 0x02
_______________________________ _______________________________
|_7_|_6_|_5_|_4_|_3_|_2_|_1_|_0_| | 0 0 0 0 0 0 0 0 | AAM 1 AAM 0x01
AAM 1
Zeroes AL and saves AL into AH.
AAM 16 for print hex
Use AMM for a hex writer with imm8 = 16, if don't want to bother masking and shifting nibbles.
F. ex. to print out the byte value EAh could be easier using aam 16 (codebytes D4 10):
AH AL AH AL +----+----+ +----+----+ | xx | EA | --- AAM 16 --> | 0E | 0A | +----+----+ +----+----+
Then print value in AH followed by AL.
AAM/AAD 16 for packed/unpacked BCD conversion
AAM/AAD 16 also converts between packed/unpacked BCD:
+----+----+ <--- AAM 16 ------ +----+----+ | 08 | 09 | | 00 | 89 | +----+----+ ------ AAD 16 ---> +----+----+
AAM 128
Simple test for Scan-1 Break Code read from 8042. Break codes have bit7 set. Separate msb, sign (0 or 1) into AH from AL using aam 128 (codebytes D4 80):
AH AL AH AL +----+----+ +----+----+ | xx | FF | --- AAM 128 --> | 01 | 7F | +----+----+ +----+----+