AAM divides AL by 10 and puts the quotient in AH and the remainder in AL. Whatever was in AH before is ignored and overwritten. SF, ZF and PF are set from the new AL; OF, AF and CF are undefined.

Its intended use is after multiplying two unpacked BCD digits: MUL leaves their product, at most 9 × 9 = 81, in AX, and AAM turns it into two unpacked digits, tens in AH and ones in AL.

Prints 56.
MOV AL, 7
MOV BL, 8
MUL BL ; AX = 56
AAM ; AH = 5, AL = 6
OR AX, 3030h ; both digits -> characters
MOV BX, AX
MOV DL, BH
MOV AH, 02h ; DOS: print DL
INT 21h
MOV DL, BL
MOV AH, 02h
INT 21h

Printing a number

Because it simply divides by 10, AAM is the quickest way to print any number 0–99 that is in AL: after AAM, add '0' (30h) to AH and to AL, or OR AX, 3030h, and print AH first. This works on any binary value, not only on BCD products, which is why AAM appears in so many small programs.

MOV AL, 42
AAM ; AH = 4, AL = 2
OR AX, 3030h ; AH = '4', AL = '2'

Pitfalls

Only AL is divided. For a value of 100 or more, AH gets 10 or more and is no longer a single digit; values up to 65535 need DIV by 10 in a loop. Since AAM reads AL alone, a product larger than 255 left in AX by MUL is not handled.

Encoding and later CPUs

AAM is encoded as the two bytes D4h 0Ah, and the second byte is the divisor. Intel processors use whatever value is there, so DB 0D4h, 16 splits AL into two hexadecimal digits; later Intel manuals document this, but assemblers of the 8086 era write only plain AAM. A divisor byte of 0 raises interrupt 0, like a division by zero. AAM is not available in 64-bit mode.