News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Mixing DWORD's and QWORDs

Started by sjums, January 24, 2012, 01:30:09 PM

Previous topic - Next topic

sjums

Hello..

So, I want this to be possible (which it isn't atm.)

    local time :SYSTEMTIME
    local fTime :FILETIME

    local lft :QWORD ;low file time
    local hft :QWORD ;high file time
    local tft :QWORD ;total file time

    invoke GetLocalTime,addr time
    invoke SystemTimeToFileTime,addr time,addr fTime
   
    mov lft,fTime.dwLowDateTime ;ofc, not possible
    mov hft,fTime.dwHighDateTime
   
    sal hft,32 ;shift HighDateTime left 32 bits
    add tft,hft ;add HighDateTime to total
    add tft,lft :add low to total


As you can see I would like to convert the current time to a FILETIME, the FT have a dwLowDateTime and a dwHighDateTime. In order to mix those two into a int64 i need to shift the dwHighDateTime 32 bits to the left and add it to the dwLowDateTime. (MSDN says so here..)

and I would like that to be in the tft (totalFileTime).

Problem is, how do i move the 32bit dwHighDateTime into the 64bit hft variable?

Also, Is there a register that can store 64bit ints? as I see it right now, i can't see how to move around those values  :eek

Thanks in advance, awesome people  :lol

MichaelW

There is no need to move anything. The two members of the FILETIME structure are (intentionally) in the same position as they would be in a 64-bit variable, with the high-order DWORD at the higher address. This is why, for example, a ULARGE_INTEGER union can be accessed as two DWORDs or as a single QUADWORD, both at the same starting address.

So basically what I'm trying to say is that there in no need to mix dwLowDateTime and a dwHighDateTime into a int64, you can just access the FT structure as an int64.


eschew obfuscation

sjums


dedndave

the filetime structure looks something like this
FILETIME       STRUCT
  dwLowDateTime  dd ?
  dwHighDateTime dd ?
FILETIME       ENDS

your code declares it like this
        local   fTime:FILETIME
so, you can access the low and high dwords directly
        mov     eax,ftime.dwLowDateTime
        mov     edx,ftime.dwHighDateTime

the 2 dwords, together, also form a qword
        mov     edi,offset fTime ;address of a qword
if you have a place that actually requires a qword form, you can use "qword ptr fTime", and it will be treated as a qword
        fild qword ptr fTime

qWord

it should be said, that the FPU only supports signed data types, thus FILD interprets the QWORD as a SQWORD.
FPU in a trice: SmplMath
It's that simple!

MichaelW

For the x86 processors the byte order for multi-byte numbers as stored in memory is the reverse of the order as stored in a register, and the reverse of the order in which we normally write numbers. IOW, multi-byte numbers are stored in memory with the low-order byte at the lowest address and the high-order byte at the highest address. So a QWORD is stored with the low-order DWORD at the lowest address and the high-order DWORD at the highest address, a DWORD is stored with the low-order WORD at the lowest address and the high-order WORD at the highest address, and so on.

And this code:

mov lft,fTime.dwLowDateTime ;ofc, not possible
mov hft,fTime.dwHighDateTime

sal hft,32 ;shift HighDateTime left 32 bits
add tft,hft ;add HighDateTime to total
add tft,lft :add low to total

Has a major problem in that the instructions you are using, like most x86 instructions, support only one memory operand.

To get the DWORD components into the QWORD you simply need to move the DWORD components into their correct positions in the QWORD. You can do the moves by using a DWORD register as an intermediary, or you can use the stack via push/pop. And note that in your code you can reference the low-order DWORD of tft as "DWORD PTR tft", and the high-order DWORD as "DWORD PTR tft+4".
eschew obfuscation

dedndave

Quote from: qWord on January 24, 2012, 07:33:33 PM
it should be said, that the FPU only supports signed data types, thus FILD interprets the QWORD as a SQWORD.

yah - it was the only case i could think of where you might want a qword (other than as a forum member)   :P

GregL

#7
Just a note, the maximum legitimate FILETIME value (7FFF35F4EFD3E980h or December 31, 30827 12:59:59 PM) is less than the maximum signed QWORD so working with FILETIME values on the FPU is OK.

Another note, there is a problem with casting a FILETIME as a QWORD, it can cause alignment faults on 64-bit Windows.  See FILETIME on MSDN and this http://blogs.msdn.com/b/oldnewthing/archive/2004/08/25/220195.aspx.  I'm not sure if "on 64-bit Windows" means 32-bit code run on 64-bit Windows or 64-bit code run on 64-bit Windows or both. [Edit] I would think this is only a problem with 64-bit code on 64-bit Windows, but I can't be sure.


sjums

From the help of my favorite snail, I think I understand what you're saying MichaelW, and also a 64bit thanks to qword for wiping away my worries :D

One day, I'm gonna be just as big and clever as you guys!!  :bg

GregL

sjums,

Here's some code:



.DATA
   
    qwTime QWORD      0 
    fTime1 FILETIME   <>
    fTime2 FILETIME   <>
    sTime  SYSTEMTIME <> 

.CODE

    INVOKE GetSystemTime, ADDR sTime
    INVOKE SystemTimeToFileTime, ADDR sTime, ADDR fTime1
   
    ; copy a FILETIME to the QWORD
    mov eax, fTime1.dwLowDateTime
    mov edx, fTime1.dwHighDateTime
    mov DWORD PTR qwTime, eax
    mov DWORD PTR qwTime+4, edx
   
    ; do some math with the QWORD
   
    ; copy the QWORD to a FILETIME
    mov eax, DWORD PTR qwTime
    mov edx, DWORD PTR qwTime+4
    mov fTime2.dwLowDateTime, eax
    mov fTime2.dwHighDateTime, edx