Hello again!

I think I've got a handle on the 32-bit world having come from 16-bit land. Now I've got a new problem. 64-bit words! How do I deal with these large numbers, such as returned by GetDiskFreeSpaceEx?

Is there something like dwtoa, maybe utoa, that can convert this? I can deal with the carry flag to do math, but how would I go about converting to ASCII? If I take the approach of dwtoa and dividie by 10, I'll overflow if I start with something larger than 20.? billion.
Posted on 2001-08-24 00:26:43 by Newguy
Maybe it helps:
; ########################################################################
Long2StrEA PROC Uses edi ecx,vr_:QWORD, lpstr_:DWORD, fld_:DWORD
Local lc1:QWORD, lc5:DWORD
Local lc2:DWORD, lc4:DWORD
Local lc3:WORD, oldcw:WORD
mov lc5,1
jmp l2sA
Long2StrEA ENDP
; ########################################################################
LongToStrA PROC Uses edi ecx,vr_:QWORD, lpstr_:DWORD, fld_:DWORD
Local lc1:QWORD, lc5:DWORD
Local lc2:DWORD, lc4:DWORD
Local lc3:WORD, oldcw:WORD
mov lc5,null
l2sA:: mov lc4,null
push dword ptr vr_
push dword ptr vr_+4
pop dword ptr lc1+4
pop dword ptr lc1
; movq MM0,vr_
; movq lc1,MM0
; emms
finit
mov edi,lpstr_
cmp dword ptr vr_+4,80000000h
jb @F
cmp dword ptr vr_+4,80000000h
ja l4
cmp dword ptr vr_,null
jne l4
mov ,byte ptr '0'
inc edi
jmp exit
l4: mov ,byte ptr '-'
inc edi
not dword ptr lc1
not dword ptr lc1+4
add dword ptr lc1,1
adc dword ptr lc1+4,null
@@: fstcw oldcw
mov ax,oldcw
or ah,RC_TO_NULL
mov lc3,ax
fldcw lc3
mov lc2,10
fild lc2
push 'x'
l1: fild lc1
fprem
fistp lc2
inc lc4
cmp lc5,null
jz @F
test lc4,3
jnz @F
push "'"-'0'
inc lc4
@@: push lc2
fild lc1
fdiv st,st(1)
fistp lc1
cmp dword ptr lc1,null
jne l1
cmp dword ptr lc1+4,null
je l2
jmp l1
l2: fldcw oldcw
mov ecx,fld_
sub ecx,lc4
jc @F
jcxz @F
l3: push ' '-'0'
inc lc4
loop l3
@@: pop eax
cmp eax,'x'
je exit
add al,'0'
mov ,al
inc edi
jmp @B
exit: mov eax,lc4
mov ,bl
ret
LongToStrA ENDP
;---------------
Just use it!
Posted on 2001-08-24 02:25:55 by Alexey
Thanks for the code Alexey, but I see that it uses floating point instructions. I was hoping to find something that stayed with the "basic" instruction set. After all, we are talking about a 64 bit integer, and not a floating point number.

Is it possible that assembly people haven't gotten into the 64 bit side of the x86? I can't believe that! C can deal with it (evil grin)....

There must be some support out there somewhere...

If I could only find it... :) :) :)
Posted on 2001-08-25 01:27:40 by Newguy
Visual Studio has some asm source code for long ints - multiply, divide and shift routines. I don't see anything for convert to ASCII though. But with a long div you could do the same thing as dwtoa.

I don't think I can post it because of copyright issues, but perhaps the SDK has something similar???

:)
Posted on 2001-08-25 21:18:02 by S/390
movq mm0(or)data64, mm0

THen, there is a mmx instruction to 'unpack' a QWORD to 2 DWORDs.

But, that might not be the answer to your question because most likely that call was not written with MMX in mind. So, what you have to do is go to the API reference and some of the VS incluses and figure out how it returns a QWORD using 2 DWORDS instead. Maybe returned in eax and ebx?
Posted on 2001-08-25 22:38:26 by Kenny
By looking in our handy-dandy Intel manual we see that the DIV instruction can divide EDX:EAX, a 64-bit number? You can break your number in half, then convert the parts separately. If you divide your 64-bit number by 1,000,000,000 - you will be able to convert a numbers up to 2^32 * 1,000,000,000. Let me throw down some code....

.data
Bit64 QWORD 0FF0000000000h ;wish I had this many pennies...
Big10 dd 1000000000
PartLow dd ?
PartHigh dd ?
PrintStr db "Big number: %lu%.9lu",0
TooBigText db "Sorry, number is too big!",0
PrintBuff db 256 dup (?)
.code
mov eax, DWORD PTR Bit64
cmp eax,3B9ACA00h
jge TooBig
mov edx, DWORD PTR Bit64 + 4
div Big10
mov PartLow, edx ;0 thru 999999999
mov PartHigh, eax
invoke wsprintf, addr PrintBuff,addr PrintStr,PartHigh,PartLow
jmp Continue
TooBig:
invoke lstrcpy,addr PrintBuff,addr TooBigText
Continue:

Posted on 2001-08-26 12:38:15 by bitRAKE
I'll write a 64bit version of the Print_16 function.
Posted on 2001-08-26 18:51:29 by eet_1024
"too many numbers to not have commas!"

Hehaha, I just yesterday posted a routine that does dwtoa and inserts commas, in Mel's thread:

http://www.asmcommunity.net/board/index.php?topic=784

:)
Posted on 2001-08-26 21:08:11 by S/390
Very nice approach to the problem bitRAKE. That should handle GetDiskFreeSpaceEx for the forseeable future. :)

I do like the comma idea. It's easy to do afterward but to have them already inserted would save that extra loop.

Thank you all very much for your help. :)
Posted on 2001-08-26 21:32:44 by Newguy
I have over 100gigs right now, maybe I should go ahead and code a 128bit version. :)
Posted on 2001-08-26 21:41:38 by bitRAKE