flat assembler
Message board for the users of flat assembler.

Index > Windows > Weird QueryPerformanceFrequency Error

Author
Thread Post new topic Reply to topic
pal



Joined: 26 Aug 2008
Posts: 227
pal
Right, I don't know if there are any known errors for this API, but I cant figure this one out myself. I have some code where I am timing and I can get two strange outcomes:

1. The QPF returns 0 for some reason. I then add in an error output (GetLastError, FormatMessageA, MessageBoxA) and then the code will execute fine.

2. The QPF runs fine. I add in a MessageBoxA output and then the QPF returns 0.

Below is an example code of such:

Code:
format PE console
entry start

include '..\INCLUDE\Win32ax.inc'

section '.code' code readable executable
start:
    push    lpFrequency
 call    [QueryPerformanceFrequency]
 test    eax,eax
     jnz             @F
  invoke  MessageBox,0,<'ERROR'>,0,0
  ret
 ; Execute the code
@@:   push    lpStart
     call    [QueryPerformanceCounter]
   
    mov             ebx,1000
    
@@:     push    szStringTwo
 push    szStringOne
 call    strcmp
      dec             ebx
 jnz             @B
  
    push    lpStop
      call    [QueryPerformanceCounter]
   fild    qword [lpStop]
      fild    qword [lpStart]
     fsubp
       fild    qword [lpFrequency]
 fdivp
       fstp    qword [lpTime]
      push    dword [lpTime+4]
    push    dword [lpTime]
      push    szTime
      call    [printf]
    add             esp,12
      ret 

proc        strcmp,szOne,szTwo
  push    esi edi
     mov     esi, [szOne]
        mov     edi, [szTwo]
        and     eax, 0
@@: inc   esi
 inc     edi
 mov     dl, [esi]
   cmp     dl, [edi]
   jne     @f
  or              dl, dl
      jnz     @b
  mov     eax,1
@@:        pop             edi esi
     ret 
endp

section '.idata' import readable writeable
    library         MSCVRT,'MSVCRT.DLL',\
                            KERNEL,'KERNEL32.DLL',\
                          USER,'USER32.DLL'
                         
    import          USER,\
                             MessageBox,'MessageBoxA'
  
    import          MSCVRT,\
                           printf,'printf'
                           
    import          KERNEL,\
                           QueryPerformanceCounter,'QueryPerformanceCounter',\
                              QueryPerformanceFrequency,'QueryPerformanceFrequency'

lMultiplier              dw      10000
lpTime                 dq      ?
lpFrequency                dq      ?
lpStart                    dq      ?
lpStop                     dq      ?

szTime                 db      "Time taken: %Lf",0

szStringOne    db      'Hello',0
szStringTwo              db      'Hello',0
    


If you remove the invoke MessageBox line then the code works fine, but if it is there then the MessageBox call is executed (as QPF returns 0).

This to me is a strange error and I cannot figure out what is wrong Confused

Cheers, pal.
Post 12 Oct 2009, 18:10
View user's profile Send private message Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
Haven't looked at it, but I believe the return for the function needs to be aligned by 4 for the "Query" functions.

_________________
----> * <---- My star, won HERE
Post 12 Oct 2009, 18:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16861
Location: In your JS exploiting you and your system
revolution
IIRC the qwords should be align by 8.
Post 12 Oct 2009, 18:48
View user's profile Send private message Visit poster's website Reply with quote
windwakr



Joined: 30 Jun 2004
Posts: 827
Location: Michigan, USA
windwakr
Post 12 Oct 2009, 18:50
View user's profile Send private message Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
revolution: Do you mean like:

Code:
lpTime                  dq      ?
lpFrequency                dq      ?
lpStart                    dq      ?
lpStop                     dq      ? 
align 8
    


If so then that doesn't work. I also tried with the aligns in between each variable. I also tried putting it before. (Sorry I haven't had to use align x before).

I also tried putting align 4 and align 8 after the call to QPF but that didn't do anything either, if that is what you meant me to do.
Post 12 Oct 2009, 18:53
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16861
Location: In your JS exploiting you and your system
revolution
The align should be before the dq's
Post 12 Oct 2009, 18:54
View user's profile Send private message Visit poster's website Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
Yeah I tried that too:

Code:
align 8
lpTime                      dq      ?
lpFrequency                dq      ?
lpStart                    dq      ?
lpStop                     dq      ? 
    
Post 12 Oct 2009, 18:56
View user's profile Send private message Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
Weird, OK it is working now. I put all of the variables into a .data section instead of having them in the .idata section.

Is that normal? I did still need the align 8 though.
Post 12 Oct 2009, 18:58
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
pal, try again, you probably put "align 8" before lMultiplier but you must put it above lpTime.

[edit]Also, add a separate section for data (it worked for me without this fix but it is still wrong not doing it), you are currently using the import section for more purposes than intended. You can also define just a data section and then use the "data import" directive inside the section.[/edit]
Post 12 Oct 2009, 18:59
View user's profile Send private message Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
Loco: I got it fixed, but cheers :p

Any ideas why it had to be in its own (well with the rest of the 'variables') .data section rather than .idata. I have never had this problem before.

Do C/C++ compilers automatically align the data as I tried the code in C++ and it worked fine.
Post 12 Oct 2009, 19:04
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16861
Location: In your JS exploiting you and your system
revolution
There is nothing special about the import section, it is just another data section that happens to contain the imports.

Most HLL compilers will always align data to "natural" boundaries. This is standard good programming practice.
Post 12 Oct 2009, 19:13
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: 16861
Location: In your JS exploiting you and your system
revolution
One way of making sure all data is aligned without putting in oodles of align's is to order all the data top-down.
Code:
align 16 ;our one and only align
xmm_value_1 dq ?,?
...
xmm_value_n dq ?,?
quad_value_1 dq ? ;guaranteed aligned by 8
...
quad_value_n dq ?
dword_value_1 dd ? ;guaranteed aligned by 4
...
dword_value_n dd ?
word_value_1 dw ? ;guaranteed aligned by 2
...
word_value_n dw ?
byte_value_1 db ? ;guaranteed aligned no matter what
...
byte_value_n db ?    
Post 12 Oct 2009, 19:20
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
pal, sorry, I didn't see your second post Razz

It was the alignment thing the problem here, using a data section is just to be safe.

Your C/C++ compiler probably aligned your variables because of the optimization settings, but I think I have read in some forum (or blog) about problems with this functions even with C/C++. I don't know how it is possible that Microsoft does not document the alignment requirement for this functions...

PS: Hey, here I found something: http://bobmoore.mvps.org/Win32/w32tip75.htm
Post 12 Oct 2009, 19:28
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
revolution, but he is marking the entire section as the import table that way, the spec really states that it is OK doing so? What would be OK is this:
Code:
section '.data' readable writeable
data import
        library         MSCVRT,'MSVCRT.DLL',\
                                KERNEL,'KERNEL32.DLL',\
                                USER,'USER32.DLL'
                                
        import          USER,\
                                MessageBox,'MessageBoxA'
        
        import          MSCVRT,\
                                printf,'printf'
                                
        import          KERNEL,\
                                QueryPerformanceCounter,'QueryPerformanceCounter',\
                                QueryPerformanceFrequency,'QueryPerformanceFrequency'
end data

align 8
lpTime                  dq      ?
lpFrequency             dq      ?
lpStart                 dq      ?
lpStop                  dq      ?

lMultiplier             dw      10000

szTime                  db      "Time taken: %Lf",0
szStringOne     db      'Hello',0
szStringTwo             db      'Hello',0
    
Post 12 Oct 2009, 19:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16861
Location: In your JS exploiting you and your system
revolution
As long as the imports start at offset 0 in the import section then there is no restriction upon the length of that section, so you can put as much data following the imports in there as you please. Windows has no way of "knowing" that the data is not needed for the imports.
Post 12 Oct 2009, 19:37
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Quote:

Windows has no way of "knowing" that the data is not needed for the imports.
It could validate the data structure and find out that some bytes of the import data are unreachable and hence consider the whole thing invalid even though the import data itself is completely usable.

But, are you saying this because it is actually documented as you describe or it is just common sense that could be proven wrong in the future?
Post 12 Oct 2009, 20:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 16861
Location: In your JS exploiting you and your system
revolution
Windows can't validate the imports in the way you suggest since the imports can be formatted in so many different ways. You could put all the function name strings at the end if you wanted to. Windows won't try to validate that you have not sneaked in some naughty data structures in between various bits.
Post 12 Oct 2009, 20:10
View user's profile Send private message Visit poster's website Reply with quote
pal



Joined: 26 Aug 2008
Posts: 227
pal
Cheers for all the help. I am still confused as to why it worked when I added some other APIs, I guess it just did something to the alignment...

That is a good idea revolution about putting the larger variables at the top by the way.

Cheers, pal.
Post 12 Oct 2009, 20:25
View user's profile Send private message 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-2019, Tomasz Grysztar.

Powered by rwasa.