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.
MOV AL, 7MOV BL, 8MUL BL ; AX = 56AAM ; AH = 5, AL = 6OR AX, 3030h ; both digits -> charactersMOV BX, AXMOV DL, BHMOV AH, 02h ; DOS: print DLINT 21hMOV DL, BLMOV AH, 02hINT 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, 42AAM ; AH = 4, AL = 2OR 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.