如何从我在 MASM 汇编程序中调用的 C 函数调用 printf?
How to call printf from a C function that I call in the MASM assembler?
我有一个名为 C.c 的 C 文件,目前在该文件中我有一个函数可以比较两个数字并将较大的数字保存到寄存器 eax。
我需要帮助创建第二个函数,该函数将在内部调用 printf
并打印一些文本。如何在我可以从 MASM 汇编程序调用的 C 中添加对 printf
的支持?
我的masm文件:
TITLE MASM Template (main.asm)
.386
.model FLAT
.stack 4096
WriteString PROTO stdcall
ReadChar PROTO stdcall
Crlf PROTO stdcall
ExitProcess PROTO stdcall:DWORD
greater PROTO C :DWORD, :DWORD
.data
PorukaZaIspis db "Poruka za ispis", 0
.code
_main PROC
push 8
push 3
call greater
call Crlf
mov edx, OFFSET PorukaZaIspis
call WriteString
call ReadChar
Invoke ExitProcess, 0
_main ENDP
END _main
END
我的 C.c 文件:
int greater(int a, int b) {
if ( a > b)
return a;
else
return b;
}
您需要 link 到适当的库(例如 msvcrt.lib
)并且您需要知道函数的导出名称。为了检测我使用的名称 dumbinGUI.
C 函数的调用约定称为"cdecl"。参数被压入堆栈,并且必须在调用后调整堆栈。如果将函数声明为 PROTO C
.
,则可以让 MASM 使用 INVOKE
完成该工作
示例:
test.asm:
.686
.model FLAT
INCLUDELIB msvcrt.lib
printf PROTO C, :VARARG
exit PROTO C, :DWORD
; Functions in C.c:
greater PROTO C :DWORD, :DWORD ; Declaration of greater (int,int)
hello PROTO C ; Declaration of hello (void)
.data
fmt db "%s %u", 10, 0 ; '10': printf of msvcrt.dll doesn't accept "\n"
PorukaZaIspis db "Message from ASM: ", 0
.code
_main PROC
invoke greater, 8, 3
call output ; "Message from ASM ..."
invoke hello ; "Message from C ..."
invoke exit, 0
_main ENDP
output PROC ; ARG: EAX
invoke printf, OFFSET fmt, OFFSET PorukaZaIspis, eax
ret
output ENDP
END _main
让我们在 C 文件中添加一个输出函数:
C.c:
#include <stdio.h>
void hello ()
{
puts ("Message from C: hello");
}
int greater(int a, int b)
{
if ( a > b)
return a;
else
return b;
}
播放以下批处理文件:
@ECHO OFF
SET VS_PATH=<Full\Path\to\Visual Studio\e.g.\C:\Program Files\Microsoft Visual Studio 10.0>
SET PATH=%VS_PATH%\VC\bin
SET LIB=%VS_PATH%\VC\lib
SET INCLUDE=%VS_PATH%\VC\include
SET CALLER=test.asm
SET CALLEE=C.c
SET TARGET=test.exe
echo cl_first
del %TARGET%
call :cl_first %CALLER% %CALLEE% %TARGET%
if exist %TARGET% %TARGET%
echo.
echo ml_first
del %TARGET%
call :ml_first %CALLER% %CALLEE% %TARGET%
if exist %TARGET% %TARGET%
goto :eof
:cl_first
cl /nologo /c %2
ml /nologo /Fe%3 %1 %~n2.obj /link /nologo
goto :eof
:ml_first
ml /nologo /c %1
cl /nologo /Fe%3 %~n1.obj %~n2.c /link /nologo
goto :eof
我有一个名为 C.c 的 C 文件,目前在该文件中我有一个函数可以比较两个数字并将较大的数字保存到寄存器 eax。
我需要帮助创建第二个函数,该函数将在内部调用 printf
并打印一些文本。如何在我可以从 MASM 汇编程序调用的 C 中添加对 printf
的支持?
我的masm文件:
TITLE MASM Template (main.asm)
.386
.model FLAT
.stack 4096
WriteString PROTO stdcall
ReadChar PROTO stdcall
Crlf PROTO stdcall
ExitProcess PROTO stdcall:DWORD
greater PROTO C :DWORD, :DWORD
.data
PorukaZaIspis db "Poruka za ispis", 0
.code
_main PROC
push 8
push 3
call greater
call Crlf
mov edx, OFFSET PorukaZaIspis
call WriteString
call ReadChar
Invoke ExitProcess, 0
_main ENDP
END _main
END
我的 C.c 文件:
int greater(int a, int b) {
if ( a > b)
return a;
else
return b;
}
您需要 link 到适当的库(例如 msvcrt.lib
)并且您需要知道函数的导出名称。为了检测我使用的名称 dumbinGUI.
C 函数的调用约定称为"cdecl"。参数被压入堆栈,并且必须在调用后调整堆栈。如果将函数声明为 PROTO C
.
INVOKE
完成该工作
示例:
test.asm:
.686
.model FLAT
INCLUDELIB msvcrt.lib
printf PROTO C, :VARARG
exit PROTO C, :DWORD
; Functions in C.c:
greater PROTO C :DWORD, :DWORD ; Declaration of greater (int,int)
hello PROTO C ; Declaration of hello (void)
.data
fmt db "%s %u", 10, 0 ; '10': printf of msvcrt.dll doesn't accept "\n"
PorukaZaIspis db "Message from ASM: ", 0
.code
_main PROC
invoke greater, 8, 3
call output ; "Message from ASM ..."
invoke hello ; "Message from C ..."
invoke exit, 0
_main ENDP
output PROC ; ARG: EAX
invoke printf, OFFSET fmt, OFFSET PorukaZaIspis, eax
ret
output ENDP
END _main
让我们在 C 文件中添加一个输出函数:
C.c:
#include <stdio.h>
void hello ()
{
puts ("Message from C: hello");
}
int greater(int a, int b)
{
if ( a > b)
return a;
else
return b;
}
播放以下批处理文件:
@ECHO OFF
SET VS_PATH=<Full\Path\to\Visual Studio\e.g.\C:\Program Files\Microsoft Visual Studio 10.0>
SET PATH=%VS_PATH%\VC\bin
SET LIB=%VS_PATH%\VC\lib
SET INCLUDE=%VS_PATH%\VC\include
SET CALLER=test.asm
SET CALLEE=C.c
SET TARGET=test.exe
echo cl_first
del %TARGET%
call :cl_first %CALLER% %CALLEE% %TARGET%
if exist %TARGET% %TARGET%
echo.
echo ml_first
del %TARGET%
call :ml_first %CALLER% %CALLEE% %TARGET%
if exist %TARGET% %TARGET%
goto :eof
:cl_first
cl /nologo /c %2
ml /nologo /Fe%3 %1 %~n2.obj /link /nologo
goto :eof
:ml_first
ml /nologo /c %1
cl /nologo /Fe%3 %~n1.obj %~n2.c /link /nologo
goto :eof