flat assembler
Message board for the users of flat assembler.

Index > Windows > QPC and QPF in Assembly interpretation.

Author
Thread Post new topic Reply to topic
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie 02 Jun 2015, 04:58
I could use some advise on how to properly interpret (QueryPerformanceCounter) QPC and QPF (QueryPerformanceFrequency) into assembly (64-bit windows);

This is from MSDN:
Code:
LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;    


This is the interpretation test code I wrote;
Code:
format PE64 console
include 'win64axp.inc'

        mov     rsi,1000 ;loop 1000 times
.again:
        mov     rcx,freq
        cinvoke QPF
        mov     rcx,starting
        cinvoke QPC

        ;*************************
        ;Activity to be timed
        mov     rax,rsp
        call    prtreg
        ;*************************

        mov     rcx,ending
        cinvoke QPC
        call    newline

        ;Get the difference between ending and starting
        ;Convert others from integer to double for later use
        mov     rax,[ending]
        mov     rbx,[starting]
        sub     rax,rbx     ;Get the difference
        call    int2dbl       ;routine to convert int in rax to double
        mov     [elapsed],rax ;Copy the double to elapsed
        mov     rax,[freq]
        call    int2dbl
        mov     [freq],rax

        ;ElapsedMicroseconds.QuadPart *= 1000000;
        ;ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
        fld     [rate]      ;1000000.00
        fld     [elapsed]
        fmul    st0,st1
        fld     [freq]
        fdiv    st0,st1
        fstp    [sec]

        ;Display the result in seconds??
        mov     rax,[sec]
        call    prtdbl
        mov     al,'s'
        call    prtchr
        call    newline
        finit
        dec     rsi
        jnz     .again

call exitp
elapsed rq 1
starting rq 1
ending rq 1
freq rq 1
rate dq 1000000.00
sec dq 0.0
;....
;....

;my other routines

;Import table down below
data import
     library msvcrt,'msvcrt.dll',kernel32,'kernel32.dll'
     import msvcrt,\
     EXIT,'exit',putchar,'putchar',getchar,'getchar'
     import kernel32,\
     QPC,'QueryPerformanceCounter',QPF,'QueryPerformanceFrequency'
end data    


Is this the correct interpretation of QPC / QPF into assembly or there are some other technical things that I am missing?

Thanks in advance.
Post 02 Jun 2015, 04:58
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20289
Location: In your JS exploiting you and your system
revolution 02 Jun 2015, 05:15
I have this 32-bit code. Perhaps you can compare to your code.
Code:
        ;definitions
        QPC_start               dq ?
        QPC_end                 dq ?
        QPC_freq                dq ?
        generate_time           dd ?
        ;...
        invoke  QueryPerformanceFrequency,addr QPC_freq
        invoke  QueryPerformanceCounter,addr QPC_start
        ;... <do stuff>
        invoke  QueryPerformanceCounter,addr QPC_end
        fild    [QPC_end]
        fild    [QPC_start]
        fsubp
        fild    [QPC_freq]
        fdivp
        mov     [generate_time],1000            ;convert to milliseconds
        fimul   [generate_time]
        fistp   [generate_time]    
Post 02 Jun 2015, 05:15
View user's profile Send private message Visit poster's website Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie 02 Jun 2015, 05:22
Thanks revo. I'll test this later.

One more question,

why there is no kernel64? AFAIK, MS generally has different argument policy for both 32-bit and 64-bit DLL/lib etc. Shouldn't kernel32 takes argument from the stack instead of RCX?
Post 02 Jun 2015, 05:22
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20289
Location: In your JS exploiting you and your system
revolution 02 Jun 2015, 05:39
fasmnewbie wrote:
why there is no kernel64?
It's complicated. I don't know all the details but from what I understand it is because lots of existing programs would break if the kernel32 name is changed. Yay, for backward compatibility.

So 64-bit code binds to kernel32 and 32-bit code also binds to kernel32. The OS has to figure out which system DLL is being referenced (32-bit or 64-bit) at runtime.
Post 02 Jun 2015, 05:39
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.