shr edx,1 ; shift dividend right one bit
rcr eax,1
or ebx,ebx
jnz short L5 ; loop until divisor < 4194304K
div ecx ; now divide, ignore remainder
mov esi,eax ; save quotient
;
; We may be off by one, so to check, we will multiply the quotient
; by the divisor and check the result against the orignal dividend
; Note that we must also check for overflow, which can occur if the
; dividend is close to 2**64 and the quotient is off by 1.
;
mul dword ptr HIWORD(DVSR) ; QUOT * HIWORD(DVSR)
mov ecx,eax
mov eax,LOWORD(DVSR)
mul esi ; QUOT * LOWORD(DVSR)
add edx,ecx ; EDX:EAX = QUOT * DVSR
jc short L6 ; carry means Quotient is off by 1
;
; do long compare here between original dividend and the result of the
; multiply in edx:eax. If original is larger or equal, we are ok,
; otherwise subtract one (1) from the quotient.
;
cmp edx,HIWORD(DVND) ; compare hi words of result and
original
ja short L6 ; if result > original, do subtract
jb short L7 ; if result < original, we are ok
cmp eax,LOWORD(DVND); hi words are equal, compare lo words
jbe short L7 ; if less or equal we are ok, else
;subtract
L6:
dec esi ; subtract 1 from quotient
L7:
xor edx,edx ; edx:eax <- quotient
mov eax,esi
;
; Just the cleanup left to do. edx:eax contains the quotient. Set the
; sign according to the save value, cleanup the stack, and return.
;
L4:
dec edi ; check to see if result is negative
jnz short L8 ; if EDI == 0, result should be negative
neg edx ; otherwise, negate the result
Listing B.2 (continued)
Understanding Compiled Arithmetic 533
22_574817 appb.qxd 3/16/05 8:45 PM Page 533