Unsigned 64-bit Divide
Posted: Mon Jul 25, 2011 1:55 am
I am having trouble with 64-bit divides on a 32-bit machine
I built a printf routine in a normal project (ie, standard headers, etc are included) which works well, and has been thouroughly tested.
When I copied this code into my new kernel (standard headers, etc not included) I have problems when I print long long integers, eg:
As this is a 32-bit machine, it will access the _aulldiv function, which (for testing purposes) I have borrowed some code from the Microsoft Research website.
When I use the print statements above, the result I get is 4507997673881650.
It looks like it is turning the sign bit on for some reason. To test this theory, I tried using this printf statement:
With this statement it works correctly.
As all this works just fine when using C libraries, I assume that it must be my modified _aulldiv function (listed below).
However, I just can't see how the sign bit is getting turned on...
I built a printf routine in a normal project (ie, standard headers, etc are included) which works well, and has been thouroughly tested.
When I copied this code into my new kernel (standard headers, etc not included) I have problems when I print long long integers, eg:
Code: Select all
printf ("%lld\n", 50);
printf ("%llu\n", 50);
When I use the print statements above, the result I get is 4507997673881650.
It looks like it is turning the sign bit on for some reason. To test this theory, I tried using this printf statement:
Code: Select all
printf ("%llu\n, (unsigned long long int)50);
As all this works just fine when using C libraries, I assume that it must be my modified _aulldiv function (listed below).
However, I just can't see how the sign bit is getting turned on...
Code: Select all
; The stack:
;
; | |
; |-------------------| +32
; | (Hi)|
; | - - - - - - - - - | +28
; | Divisor (Lo)|
; |-------------------| +24
; | (Hi)|
; | - - - - - - - - - | +20
; | Dividend (Lo)|
; |-------------------| +16
; | Return Address|
; |-------------------| +12
; | ESI |
; |-------------------| +8
; | EBP |
; |-------------------| +4
; | EBX |
; --------------------- ESP (0)
[BITS 32]
[GLOBAL __aulldiv]
[SECTION .TEXT]
__aulldiv:
; Setup stack frame
PUSH ESI
PUSH EBP
PUSH EBX
MOV EBP, ESP
mov ecx,[ebp+24] ; lower divisor
mov eax,[ebp+20] ; higher dividend
xor edx,edx
div ecx
mov ebx,eax ; ebx = temporary storage
mov eax,[ebp+16] ; lower dividend
div ecx
mov edx,ebx ; recover from temporary storage
Clean:
; Clean up
POP EBX
POP EBP
POP ESI
RET