The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: Dark Schneider on January 19, 2007, 06:50:04 AM

Title: QWORD related functions
Post by: Dark Schneider on January 19, 2007, 06:50:04 AM
Hello again everyone.
I study assembly language as hobby and now I'm working on my little 'File Explorer' project and I need several basic functions to manipulate QWORD values.
I looked for those functions in the masm32 library but found nothing.
So I coded all those functions but I'm sure it's not good enough, I need it fast.

Take a look at one of those functions I coded:


;add two QWORD values, return (0=success, 1=overflow)
qwadd PROC lpSrc1:DWORD, lpSrc2:DWORD, lpDest:DWORD
    push edi
    push esi

    mov esi, lpSrc1
    mov edi, lpSrc2

    xor eax, eax
    mov ecx, dword ptr [esi]
    mov edx, dword ptr [esi+4]
    add ecx, dword ptr [edi]
    adc edx, 0
    add edx, dword ptr [edi+4]
    adc eax, 0

    mov edi, lpDest
    mov dword ptr [edi], ecx
    mov dword ptr [edi+4], edx

    pop esi
    pop edi
    ret
qwadd ENDP


Please help me find the fastest function to do basic stuffs with qword values (add, sub, mul, div, convert to/from ascii, etc.).

Thank you.

PS. In Thailand where I was born and living, Assembly language is not so popular.
Even in university they teach  C, C++, C#, Java and everything but no Assembly.
No books, no websites or classrooms about 32 bits assembly language exist.
I'm sad.  :(
Title: Re: QWORD related functions
Post by: stanhebben on January 19, 2007, 10:11:39 AM
You can perform qword arithmetic with the following macro's:

Addition and subtraction:

; eax:edx = eax:edx + srclow:srchigh
qwadd macro srclow:req, srchigh:req
  add eax, srclow
  adc eax, srchigh
endm

; eax:edx = eax:edx - srclow:srchigh
qwsub macro srclow:req, srchigh:req
  sub eax, srclow
  subb eax, srchigh
endm


Multiplication is a bit harder, but no big deal: (this functions results in a double quadword - 128 bits)

qwmul proc pdst:dword, alow:dword, ahigh:dword, blow:dword, bhigh:dword
  push edi
  mov edi, pdst
 
  mov [edi + 8], 0
  mov [edi + 12], 0
 
  mov eax, alow
  mul blow
  mov [edi + 0], eax
  mov [edi + 4], edx
 
  mov eax, ahigh
  mul blow
  add [edi + 4], eax
  adc [edi + 8], edx
 
  mov eax, alow
  mul bhigh
  add [edi + 4], eax
  adc [edi + 8], edx
 
  mov eax, ahigh
  mul bhigh
  add [edi + 8], eax
  adc [edi + 12], edx
 
  pop edi
  ret
qwmul endp


Division is the hardest one. I can't immediately recall an efficient division, maybe someone else has something.

Note: functions that return 64-bit values return their low dword in eax, and the high dword in edx.
Title: Re: QWORD related functions
Post by: Ehtyar on January 19, 2007, 10:44:38 AM
Wow, these so need to be in macros.asm. Here is a little something for qw -> dw, thanks to f0dder.

qw2dw macro src:qword, dst:dword
fld [src]
fistp [dst]
endm


Hope this helps, Ehtyar.
Title: Re: QWORD related functions
Post by: stanhebben on January 19, 2007, 10:51:19 AM
Ehtyar, the macro you gave is a 64-bit floating point to 32-bit integer conversion. If you want to convert from 64-bit to 32-bit, you can simply 'forget' the high part. (of course, the number must not be too large)
Title: Re: QWORD related functions
Post by: Ehtyar on January 19, 2007, 11:32:53 AM
Oh see i thought that was the case, lol. Guess i misunderstood f0dder when he explained, i don't know much about the fpu  :red. Anyway, might we consider making a collection of q-word functions like this?

Ehtyar.
Title: Re: QWORD related functions
Post by: Shantanu Gadgil on January 19, 2007, 11:39:49 AM
Hi Dark Schneider,
Nice to see someone else also writing a "File Explorer" thingie. I too had done one some time back and required addition routine to show the total of the file sizes in the current directory.

One question though: Why do you require to add TWO qwords? All you really require in addition of two sets of doublewords and format the final double-word set to display (in say the status bar or something), right?
The high-dword and low-dword would be for each file from the WIN32_FINDDATA, right?

So basically the upper limit for this summation would be (4294967296 * 4294967296) bytes, right? (1.844674407370955162e+19)

Nice to know you are working on a "qword functions set"  :U :U :thumbu :thumbu

Regards,
Shantanu
Title: Re: QWORD related functions
Post by: Shantanu Gadgil on January 19, 2007, 11:55:19 AM
On another note:
The following was a funtion that was required by me. I don't know if the Win32API already has something equivalent. (I did stumble upon MulDiv and the likes, but couldn't find the exact thing that I required.

I needed it for a file splitting thing that I required! (How many pieces would be created if the filesize and the chunksize is known)

Note: I have written this post under a linux box and from memory (not verified), so please don't mind any obvious mistakes!  :red :red hope there are none  :bg :bg After going home I will fix it, if anything is missing)

;dwHigh::dwLow divided by dwDivisor.
;remainder returned in address of pdwRemainder, if pdwRemainder != NULL
;quotient returned in eax :)
CompleteDivision proc dwHigh:DWORD, dwLow:DWORD, dwDivisor:DWORD, pdwRemainder:LPDWORD
LOCAL dwQuotient:DWORD

push eax
push ebx
push edx

mov edx, dwHigh
mov eax, dwLow
mov ebx, dwDivisor
div ebx
;now remainder in edx and quotient in eax
mov dwQuotient, eax
mov ebx, pdwRemainder
.if ebx != 0
mov [ebx], edx
.endif

pop edx
pop ebx
pop eax

mov eax, dwQuotient
ret
CompleteDivision endp


Cheers,
Shantanu
Title: Re: QWORD related functions
Post by: Dark Schneider on January 20, 2007, 05:44:52 AM
Thanks everyone :U
Title: Re: QWORD related functions
Post by: sinsi on January 20, 2007, 06:05:00 AM
Quote from: Stan Hebben on January 19, 2007, 10:11:39 AM

; eax:edx = eax:edx + srclow:srchigh
qwadd macro srclow:req, srchigh:req
  add eax, srclow
  adc eax, srchigh
endm

; eax:edx = eax:edx - srclow:srchigh
qwsub macro srclow:req, srchigh:req
  sub eax, srclow
  subb eax, srchigh
endm
Shouldn't that be

; eax:edx = eax:edx + srclow:srchigh
qwadd macro srclow:req, srchigh:req
  add edx, srclow
  adc eax, srchigh
endm

; eax:edx = eax:edx - srclow:srchigh
qwsub macro srclow:req, srchigh:req
  sub edx, srclow
  sbb eax, srchigh
endm

Also, I think that using EDX:EAX would be better - it seems to be a convention to have EDX as the high 32-bits.
Title: Re: QWORD related functions
Post by: Dark Schneider on January 21, 2007, 04:33:22 AM
And how to convert a QWORD integer to ASCII string and back?
I used to adapted 'dq2ascii' function coded by someone I can't remember and it works on Windows ME but not on XP.
And again my own code is too slow to be useful.
Title: Re: QWORD related functions
Post by: Shantanu Gadgil on January 21, 2007, 04:44:47 AM
Hi Dark Schneider,
What I had done was, write a "String Maths" library; add, sub, mul, div, etc for strings. Amongst all the functions, it had these

DwordToDecimalString          PROTO :DWORD,:LPTSTR
QwordToString              PROTO :DWORD,:DWORD,:LPTSTR


This QwordToString would convert the highdword to string, multiply it with the string "4294967296" and add the low dword to it.  :bg
The only reason for this was to _somehow_ use only 32bit stuff and get it done; I am sure there would a "nicer" way to do it!

I am going to post the library code, but never got around to cleaning up the code.   :red :'( :'(
Will do that and then post it!

Anyway, hope the algorithm helps for now,
Shantanu
Title: Re: QWORD related functions
Post by: Dark Schneider on January 21, 2007, 09:12:41 PM
Thank you, Shantanu Gadgil.

That's almost exactly what I had in mind (String Math) but my code is too slow.
Someone may have a better approach?
Title: Re: QWORD related functions
Post by: raymond on January 23, 2007, 02:30:29 AM
You may want to try my proc to convert signed qwords to ascii. See attached file. It covers the range of (-2^63) to (+2^63-1). (I've also sent it to hutch for evaluation and comparison with other available procedures.)

If your string representation contains a maximum of 18 digits (i.e. <10^18, i.e. less than 1,000,000,000 Gigs), I could also supply a procedure to convert such strings to a qword based on a similar approach using in part some FPU instructions.

Raymond



[attachment deleted by admin]
Title: Re: QWORD related functions
Post by: Dark Schneider on January 23, 2007, 07:34:26 AM
Thank you, raymond.

I will look into it when I return to my home next month.
Title: Re: QWORD related functions
Post by: stanhebben on January 23, 2007, 11:57:15 AM
Quote from: sinsi on January 20, 2007, 06:05:00 AM
Shouldn't that be

; eax:edx = eax:edx + srclow:srchigh
qwadd macro srclow:req, srchigh:req
  add edx, srclow
  adc eax, srchigh
endm

; eax:edx = eax:edx - srclow:srchigh
qwsub macro srclow:req, srchigh:req
  sub edx, srclow
  sbb eax, srchigh
endm

Also, I think that using EDX:EAX would be better - it seems to be a convention to have EDX as the high 32-bits.

You're right - on both points.

; edx:eax = edx:eax + srchigh:srclow
qwadd macro srclow:req, srchigh:req
  add eax, srclow
  adc edx, srchigh
endm

; edx:eax = edx:eax - srchigh:srclow
qwsub macro srclow:req, srchigh:req
  sub eax, srclow
  sbb edx, srchigh
endm