Manual de montaje de prototipos
Pregunta
Estoy escribiendo una asignación en Asamblea MASM32 y casi he completado, pero tengo 2 preguntas que me parece que no puede responder. En primer lugar, cuando compilo me sale el mensaje:
INVOCACIÓN requiere prototipo para procedimiento
&
operandos de instrucción no válida
el primero es debido a este pedazo de código:
.data?
Freq DWORD ?
Time1 DWORD ?
Time2 DWORD ?
.code
start:
invoke QueryPerformanceFrequency, addr Freq
invoke QueryPerformanceCounter, addr Time1
Ahora, sé que
La directiva INVOCACIÓN debe ir precedido de una declaración PROTO para el procedimiento que se llama.
Pero aunque me enteré de la sintaxis de la instrucción PROTO:
label PROTO [distance] [langtype] [,[parameter]:tag]
No entiendo exactamente lo que debería escribir con el fin de hacer que funcione y yo ni siquiera sé lo que está causando el segundo error o cómo solucionarlo ... = /
Editar
Ya tengo esas bibliotecas y éstas también:
.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
Estoy trabajando bajo Windows Vista sólo en caso de que también ayuda.
Editar 2
Si escribo la Frec: QWORD después de la .data me sale este mensaje de error:
uso de registro supone al error
y también el lugar donde debería añadir el
QueryPerformanceCounter PROTO :DWORD
Lo que por lo que yo sé no cometer un error, pero todavía no estoy seguro de nada ha cambiado (lo puse antes .data y después de las bibliotecas).
Solución
Con el fin de llamar a una API externa es necesario incluir el archivo correspondiente * .inc, así como el correspondiente archivo * .lib.
Trate de añadir estas declaraciones a su perfil:
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
(suponiendo \ masm32 referes a su directorio masm32)
Actualización:
El prototipo de definición básicamente le dice al ensamblador cuántos parámetros de la función respectiva espera en la pila. En su caso, la API espera un parámetro de 32 bits para estar en la pila, que se refleja en el prototipo de esta manera:
QueryPerformanceCounter PROTO :DWORD
Actualización 2:
Con el fin de utilizar la API de contador de rendimiento que necesita una palabra cuádruple. La razón es que la API espera un puntero a una palabra cuádruple (64 bits) como el parámetro (por lo tanto la DWORD en el prototipo):
LOCAL Freq :QWORD
invoke QueryPerformanceFrequency, ADDR Freq
Esto debería hacer el truco.
Update3:
Así que aquí está un ejemplo completo que funciona para mí:
.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
supongo que eso es todo :) ESI y EDI ahora contienen el resultado.