0x00876002 / 0x10 = 0x87600
, so the quotient of DX:AX / BX
doesn't fit in AX, thus you get a #DE exception. Intel's instruction reference manual (x86 SDM vol. 2) has detailed descriptions of every instruction, and the entry for div
explains this. There's an HTML extract of the div
entry here. See the x86 tag wiki for links to Intel's docs, and other stuff.
Dividing by 10h is a right shift by 1 hex digit, but the high-half of the input, DX, has 2 significant hex digits.
x86 Assembly: Division Floating Point Exception dividing by 11 is mostly a duplicate of this, and @rcgldr's answer has code for extended-precision division (e.g. 32-bit / 16-bit producing a 32-bit quotient and 16-bit remainder) using div
that works for an arbitrary 16-bit divisor.
In your specific case you're dividing by a power of 2. This is very inefficient with div
.
For these power-of-2 divisions, you should use
; input in DX:AX
shrd ax, dx, 4 ; right shift AX, shifting in bits from DX
shr dx, 4 ; separately right shift DX
; DX:AX = 0008:7600 = 0x87600 = 32-bit quotient
If you want the remainder, it's the low 4 bits of the original AX, which you should get with mov cl, al
/ and cl, 0Fh
.
SHRD only modifies its destination, not the source, so you need that 2nd shr
on DX. This makes sense for larger extended-precision shifts: you want to use a chain of SHRD instructions to shift bits into the top of each element in turn, and don't want to shift in zeros.
Or if you can't use 386 instructions like shrd
, you can emulate SHRD with a left and right shift and an OR. Original 8086 doesn't have immediate-count shifts either, so you'd need a count in CL.
; 8086-compatible version of 32-bit division by 10h, i.e. right shift by 4.
; input in DX:AX
mov bx, dx
mov cl, 16-4
shl bx, cl ; bx = the bits shifted across the 16-bit boundary into low half
mov cl, 4
shr ax, cl
shr dx, cl ; discards the bits shifted out
or ax, bx ; replace the 4 zeros at the top of AX with the bits from DX
; quotient in DX:AX
Or if you know that the result won't overflow, like in the divide-by 100h
(right shift by 8) case, you can use just one SHRD.