Instrução de protótipo de montagem
Pergunta
Estou escrevendo uma tarefa na montagem do MASM32 e quase a completei, mas tenho duas perguntas que não consigo responder. Primeiro, quando compilar, recebo a mensagem:
Invoke requer protótipo para procedimento
&
operando de instrução inválida
O primeiro é devido a este pedaço de código:
.data?
Freq DWORD ?
Time1 DWORD ?
Time2 DWORD ?
.code
start:
invoke QueryPerformanceFrequency, addr Freq
invoke QueryPerformanceCounter, addr Time1
Agora eu sei disso
A Diretiva Invoke deve ser precedida por uma declaração proto para o procedimento que está sendo chamado.
Mas mesmo que eu tenha descoberto a sintaxe da declaração proto:
label PROTO [distance] [langtype] [,[parameter]:tag]
Não entendo exatamente o que devo escrever para fazê -lo funcionar e nem sei o que está causando o segundo erro ou como corrigi -lo ... =/
Editar
Eu já tenho essas bibliotecas e também:
.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
Estou trabalhando com o Windows Vista, para o caso de ajudar também.
Editar 2
Se eu escrevo o freq: qword após o .data, recebo esta mensagem de erro:
uso do registro assumido para errar
e também onde devo adicionar o
QueryPerformanceCounter PROTO :DWORD
O que até onde eu sei não cometeu um erro, mas ainda não tenho certeza de que mudei de nada (eu o coloquei antes .Data e depois das bibliotecas).
Solução
Para chamar uma API externa, você precisa incluir o arquivo *.inc apropriado, bem como o respectivo arquivo *.lib.
Tente adicionar estas declarações à sua listagem:
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
(assumindo MASM32 refere -se ao seu MASM32 DIR)
Atualizar:
A definição de protótipo diz basicamente ao assembler quantos parâmetros a função respectiva espera na pilha. No seu caso, a API espera que um parâmetro de 32 bits esteja na pilha, o que é refletido pelo protótipo como este:
QueryPerformanceCounter PROTO :DWORD
Update2:
Para usar a API do contador de desempenho, você precisa de uma quadra. O motivo é que a API espera um ponteiro para uma quadra (64 bits) como o parâmetro (portanto, o DWORD no protótipo):
LOCAL Freq :QWORD
invoke QueryPerformanceFrequency, ADDR Freq
Isso deve fazer o truque.
Atualização3:
Então, aqui está um exemplo completo que funciona para mim:
.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
Eu acho que é isso :) Esi e EDI agora contêm o resultado.