[SOLVED] Signed 64bit multiplication on 32bit machine
Re: [SOLVED] Signed 64bit multiplication on 32bit machine
One should note that if the divisor is 2^32 or greater, you can truncate it to 32 bit precision, and the result will be at most 1 too much. By multiplying with the original divisor, you can see if the answer is larger than the dividend, and if so, subtract 1 from the answer.
Re: [SOLVED] Signed 64bit multiplication on 32bit machine
I think I have it. Whoo, it will take some time to test it...
EDIT: Ok, I tested, unsigned division works well (but -4/-2=0 rem. -4 )
EDIT2: Everything works now (also signed division). Thank you, Brendan.
My final version of code
EDIT: Ok, I tested, unsigned division works well (but -4/-2=0 rem. -4 )
EDIT2: Everything works now (also signed division). Thank you, Brendan.
My final version of code
Code: Select all
;[EBP+4+4] = LOWORD(DIVISOR)
%define ldiv dword [ebp+4+4]
;[EBP+8] = HIWORD(DIVISOR)
%define hdiv dword [ebp+8+4]
;[EBP+12] = LOWORD(NUMERATOR)
%define lnum dword [ebp+12+4]
;[EBP+16] = HIWORD(NUMERATOR)
%define hnum dword [ebp+16+4]
;[EBP-4] = HIWORD(RESULT)
%define hres dword [ebp-4]
;[EBP-8] = LOWORD(RESULT)
%define lres dword [ebp-8]
sl64:
add eax, eax
adc edx, edx
ret
div_sr64:
mov ebx, hdiv
shl ebx, 31
shr hdiv, 1
shr ldiv, 1
or ldiv, ebx
ret
int64div:
push ebp
mov ebp, esp
sub esp, 8
xor edi, edi
cmp hnum, 0
jns .next1
not lnum
not hnum
add lnum, 1
adc hnum, 0
mov edi, 1
.next1:
cmp hdiv, 0
jns .go0
not ldiv
not hdiv
add ldiv, 1
adc hdiv, 0
sub edi, 1
.go0:
;PREAMBULE
xor eax, eax
or eax, ldiv
or eax, hdiv
cmp eax, 0
jnz .go1
;INTERRUPT
int 0x0
.go1:
cmp hdiv, 0
jnz .go2
mov eax, lnum
mov edx, hnum
div ldiv
mov ecx, edx
xor edx, edx
xor ebx, ebx
jmp .not_it_all
.go2:
xor eax, eax
or eax, lnum
or eax, hnum
cmp eax, 0
jnz .go3
xor eax, eax
xor edx, edx
xor ecx, ecx
xor ebx, ebx
ret
.go3:
mov lres, 0
mov hres, 0
xor ecx, ecx
mov eax, ldiv
mov edx, hdiv
.winterfell:
test edx, 1<<31
jnz .ned_stark
call sl64
inc ecx
jmp .winterfell
.ned_stark: ;brace yourself, 64bit division is comming
mov ldiv, eax
mov hdiv, edx
mov eax, lnum
mov edx, hnum
.kings_landing:
xor ebx, ebx
or ebx, eax
or ebx, edx
cmp ebx, 0
jz .the_king_of_the_north
cmp edx, hdiv
js .lets_kill_starks
ja .lannisters_still_here
cmp eax, ldiv
js .lets_kill_starks
.lannisters_still_here:
sub eax, ldiv
sbb edx, hdiv
bts lres, ecx
.lets_kill_starks:
jecxz .the_king_of_the_north
call div_sr64
dec ecx
jmp .kings_landing
.the_king_of_the_north:
mov ebx, edx
mov ecx, eax ;remainder
mov edx, hres
mov eax, lres ;result
.not_it_all:
test edi, 1
jz .end
not ecx
not ebx
add ecx, 1
adc ebx, 0
not eax
not edx
add eax, 1
adc edx, 0
.end:
mov esp, ebp
pop ebp
ret