views:

451

answers:

1

I am writing an assignment in MASM32 Assembly and I almost completed it but I have 2 questions I can't seem to answer. First, when I compile I get the message:

INVOKE requires prototype for procedure

&

invalid instruction operands

the first is due to this piece of code:

.data?
Freq    DWORD ?
Time1   DWORD ?
Time2   DWORD ?

.code
start:
invoke QueryPerformanceFrequency, addr Freq
invoke QueryPerformanceCounter, addr Time1

now, I know that

The INVOKE directive must be preceded by a PROTO statement for the procedure being called.

but even though I found out the syntax for the PROTO statement:

label PROTO [distance] [langtype] [,[parameter]:tag]

I don't understand exactly what I should write so as to make it work and I don't even know what is causing the second error or how to fix it...=/


Edit

I already have those libraries and these also:

.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

I'm working under Windows Vista just in case that helps as well.


Edit 2

If I write the Freq :QWORD after the .data I get this error message:

use of register assumed to ERROR

and also where should I add the

QueryPerformanceCounter PROTO :DWORD

Which as far as I know didn't make an error but still I'm not sure changed anything (I placed it before .data and after the libraries).

+2  A: 

In order to call an external API you need to include the appropriate *.inc file as well as the respective *.lib file.
Try to add these statements to your listing:

include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

(assuming \masm32 referes to your masm32 dir)

Update:
The prototype definition basically tells the assembler how many parameters the respective function expects on the stack. In your case the API expects one 32bit parameter to be on the stack, which is reflected by the prototype like this:

QueryPerformanceCounter PROTO :DWORD

Update2:
In order to use the performance counter API you need a quadword. The reason is, that the API expects a pointer to a quadword (64 bit) as the parameter (therefore the DWORD in the prototype):

LOCAL Freq  :QWORD
invoke QueryPerformanceFrequency, ADDR Freq

This should do the trick.

Update3:
So here's a complete example which works for me:

    .486
    .model flat, stdcall
    option casemap :none

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\masm32.inc

    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\masm32.lib

    doPerf     PROTO

.code

start:

    invoke doPerf
    invoke ExitProcess,eax

    doPerf proc

        LOCAL Freq  :QWORD
        invoke QueryPerformanceFrequency, ADDR Freq
        mov esi, dword ptr Freq
        mov edi, dword ptr Freq+4

        ret

    doPerf endp

end start

I guess that's it :) ESI and EDI now contain the result.

jn_
is that after the .data ? or where I'm sorry I really didn't use any "QueryPerformanceCounter" before.
Luis Armando
in my example Freq is a local variable, i.e. a variable residing in a function. But you can just as well let it be defined in the data section.
jn_