Reputation: 9408
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).
Upvotes: 1
Views: 6636
Reputation: 5291
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.
Upvotes: 2