MUL takes a single operand, the multiplier. The other factor and the place for the result are fixed by the operand size:
| Operand | Multiplies | Result |
|---|---|---|
| byte (reg8/mem8) | AL × operand | AX |
| word (reg16/mem16) | AX × operand | DX:AX (DX the high word) |
The result is twice as wide as the factors, so it always fits: 255 × 255 = 65025 fits in AX. The numbers are treated as unsigned; for signed values use IMUL.
MOV AL, 6MOV BL, 7MUL BL ; AX = 42AAM ; AH = tens, AL = onesOR AX, 3030h ; both digits -> charactersMOV BX, AXMOV DL, BHMOV AH, 02h ; DOS: print DLINT 21hMOV DL, BLMOV AH, 02hINT 21h
What is not allowed
There is no immediate form on the 8086: MUL 10 does not exist, so load the constant into a register or keep it in memory. A memory operand needs a size when nothing implies it, MUL BYTE PTR [SI] or MUL WORD PTR [SI]. The size chosen decides which registers are used, so MUL BX overwrites DX even if you only expected a small result.
MOV AX, 1000MOV BX, 300MUL BX ; DX:AX = 300000 = 0004h:93E0h, CF = OF = 1
Flags
CF and OF are both set to 1 when the upper half of the result (AH for a byte multiply, DX for a word multiply) is not zero, and both are cleared when it is zero. So after MUL a JNC can tell you that the product still fits in AL or AX alone. SF, ZF, AF and PF are undefined: do not test ZF to see whether the product was zero.
Idioms and pitfalls
Multiplying by a power of two is often written as shifts (SHL AX, 1, or SHL AX, CL for larger counts), which also leave DX alone. Remember that DX is clobbered by a 16-bit MUL; save it first if it held something else.
Later CPUs
The 386 adds a 32-bit form, MUL ECX, which multiplies EAX and leaves the 64-bit result in EDX:EAX. MUL never gained an immediate or a two-operand form; those exist only for IMUL.