6:06 pm GMT
Examples
Examples » ASM
;
; _ulldiv divides two unsigned long long numbers, the dividend and the divisor
; resulting in a quotient and a remainder.
;
; input:
; edx:eax = dividend
; ecx:ebx = divisor
;
; output:
; edx:eax = quotient of division of dividend by divisor
; ecx:ebx = remainder of division of dividend by divisor
;
; destroys:
; eflags
;
PROC _ulldiv NEAR
test ecx, ecx ; divisor > 2^32-1 ?
jnz $big_divisor ; yes, divisor > 32^32-1
cmp edx, ebx ; only one division needed ? (ecx = 0)
jb $one_div ; yes, one division sufficient
mov ecx, eax ; save dividend-lo in ecx
mov eax, edx ; get dividend-hi
xor edx, edx ; zero extend it into edx:eax
div ebx ; quotient-hi in eax
xchg eax, ecx ; ecx = quotient-hi, eax =dividend-lo
$one_div: div ebx ; eax = quotient-lo
mov ebx, edx ; ebx = remainder-lo
mov edx, ecx ; edx = quotient-hi(quotient in edx:eax)
xor ecx, ecx ; ecx = remainder-hi (rem. in ecx:ebx)
ret
$big_divisor:push esi ; save temp
push edi ; variables
push edx ; save
push eax ; dividend
mov esi, ebx ; divisor now in
mov edi, ecx ; edi:ebx and ecx:esi
shr edx, 1 ; shift both
rcr eax, 1 ; divisor and
ror edi, 1 ; and dividend
rcr ebx, 1 ; right by 1 bit
bsr ecx, ecx ; ecx = number of remaining shifts
shrd ebx, edi, CL ; scale down divisor and
shrd eax, edx, CL ; dividend such that divisor
shr edx, CL ; less than 2^32 (i.e. fits in ebx)
rol edi, 1 ; restore original divisor (edi:esi)
div ebx ; compute quotient
pop ebx ; get dividend lo-word
mov ecx, eax ; save quotient
imul edi, eax ; quotient * divisor hi-word (low only)
mul esi ; quotient * divisor lo-word
add edx, edi ; edx:eax = quotient * divisor
sub ebx, eax ; dividend-lo - (quot.*divisor)-lo
mov eax, ecx ; get quotient
pop ecx ; restore dividend hi-word
sbb ecx, edx ; subtract divisor * quot. from dividend
sbb edx, edx ; 0 if remainder > 0, else FFFFFFFFh
and esi, edx ; nothing to add
and edi, edx ; back if remainder positive
add ebx, esi ; correct remaider
adc ecx, edi ; and quotient if
add eax, edx ; necessary
xor edx, edx ; clear hi-word of quot (eax<=FFFFFFFFh)
pop edi ; restore temp
pop esi ; variables
ret
ENDP _ulldiv
This category contains 2
examples, and has been viewed 47380 times.
|