[signature under construction]
What's the problem is that the number in whatever register you're
using to divide into the AX:DX dw is small enough that the resulting
answer is too large to fit into AX. That is a 'divide overflow.'
The DIV instruction *can* be used to divide a double word, but the
resulting answer *must* be small enough to fit into the AX register.
The remainder is placed into the DX register.
placed into the DX
register.
> divide a dword by a word or byte. The reference I have tells me that div
> divides dx:ax by a word. But using the div instruction I get a divide
> overflow if I put a value in dx. I'm only using a 8088 if that makes a
> difference. But I doubt that with a 386 you can divide eax, full 32bits.
Most forms of divide can only produce a result half as wide as the
dividend. When dividing a 32 bit number, you get an overflow if the
result doesn't fit in 16 bits.
To divide a 32 bit number in bx:ax by a 16 bit number in cx leaving
a 32 bit result in bx:ax and a 16 bit remainder in dx do the following:
xchg ax, bx
xor dx, dx
div cx
xchg ax, bx
div cx
On a 386 it is easier because you can divide a 64 bit value in
edx:eax and get a 32 bit result.
A 16-bit DIV (or IDIV) divides the 32-bit number in DX:AX by the specified
16-bit divisor. Unfortunately, it returns the quotient in AX and the
remainder in DX, so if the quotient is too large to fit in the 16-bit AX
register, you get a Divide Overflow.
If the divisor is smaller than the high word of the dividend (the value in
DX), you're safe, but if it's equal or larger, the result will overflow.
It's possible to safely divide any 32-bit number by any nonzero 16-bit
number by breaking the division up into two 16-bit steps:
;--------------------------------------------------
SafeDiv PROC
;Input: DX:AX = Dividend, CX = Divisor
;Output: DX:AX = Quotient, BX = Remainder, CX unaltered
;CAUTION: Does NOT check for divide-by-zero.
push ax ;save low word
mov ax,dx ;high word to AX
sub dx,dx ;Set DX = 0
div cx ;Divide the high word
mov bx,ax ;BX = quotient high word
pop ax ;Retrieve low word
div cx ;Divide remainder high:dividend low
xchg bx,dx ;Swap results into place
ret
SafeDiv ENDP
> I'm only using a 8088 if that makes a
> difference. But I doubt that with a 386 you can divide eax, full 32bits.
Actually, the 32-bit DIV on a 386 divides the 64-bit value in EDX:EAX by
the specified 32-bit divisor, so safely dividing a 32-bit dividend by any
nonzero 32-bit divisor becomes trivial:
mov eax,Dividend
sub edx,edx ;Set upper 32 bits to zero
div Divisor
;Quotient in EAX, remainder in EDX
---
Glen Blankenship
obo...@netcom.com