Re: NAFCQY [Not A FastCode Question, Yay!]: Int64 DivMod



On Wed, 27 Jul 2005 15:29:51 +0200, "Kristofer Skaug"
<nospam@xxxxxxxxx> wrote:

>Anyway it cannot be the only change needed; if I change Divisor to Int64,
>this code AV's without even coming close to executing the two lines you
>mentioned.
>Could it be that if you expand Divisor to Int64 then the location of the
>other parameters shifts?

Oh, sorry, it was a bit late and I was too quick about it :)

The Divisor would be passed by stack and not registers, and you'd have
to do some extra checks.

Here's a version that should work, at least it did for the few tests I
performed :)

I'm still not sure how you want signes to be handled. So far it
performs Abs() on both Dividend and Divisor, but this can be changed
to mimic div / mod behaviour.

procedure DivMod64_2(Dividend, Divisor: Int64; var Result, Remainder:
Int64);
asm
push ebx
push edi
push esi

mov esi, eax // esi = Result
mov edi, edx // edi = Remainder

mov ecx, [ebp+$08]
mov ebx, [ebp+$0C]

mov eax, [ebp+$10]
mov edx, [ebp+$14]

or ebx, ebx
jns @@noneg1
// force positive Divisor
neg ecx
adc ebx, 0
neg ebx

@@noneg1:
or edx, edx
jns @@noneg2
// force positive Dividend
neg eax
adc edx, 0
neg edx

@@noneg2:
// if both highwords are zero, use regular division
or ebx, ebx
jnz @@binary

or ecx, ecx // let div raise division by zero
jz @@regular

or edx, edx
jz @@regular

@@binary:
push edi
push esi

mov ebp, 64

xor esi, esi
xor edi, edi

@@loop:
shl eax, 1
rcl edx, 1
rcl esi, 1
rcl edi, 1

cmp edi, ebx // check high words
jb @@nosub
ja @@sub
cmp esi, ecx // check low words
jb @@nosub

@@sub:
sub esi, ecx // subtract divisor
sbb edi, ebx
inc eax // increment result

@@nosub:
dec ebp
jnz @@loop

pop ecx
pop ebx

mov [ebx], esi
mov [ebx+4], edi
mov [ecx], eax
mov [ecx+4], edx

jmp @@exit

@@regular:
div ecx
mov [esi], eax
mov [esi+4], 0
mov [edi], edx
mov [edi+4], 0

@@exit:
pop esi
pop edi
pop ebx
end;

.



Relevant Pages