如何从我在MASM汇编器中调用的C函数中调用printf? [英] How to call printf from a C function that I call in the MASM assembler?

查看:738
本文介绍了如何从我在MASM汇编器中调用的C函数中调用printf?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为C.c的C文件,现在在该文件中,我有一个函数可以比较两个数字并将更大的数字保存到寄存器eax中.

I have a C file called C.c and for now in that file I have one function that compares two numbers and saves the greater number to the register eax.

我需要帮助来创建第二个函数,该函数将在内部调用printf并打印一些文本.如何在MASM汇编程序中调用的C语言中添加对printf的支持?

I need help with creating the second function that will call printf inside and print some text. How to add support for printf in C that I can call from MASM assembler?

我的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

我的抄送文件:

int greater(int a, int b) {
if ( a > b)
return a;
else 
return b;
}

推荐答案

您需要链接到适当的库(例如msvcrt.lib),并且需要知道函数的导出名称.要检测名称,我使用 dumbinGUI .

You need to link to an appropriate library (e.g. msvcrt.lib) and you need to know the exported names of the functions. To detect the names I use dumbinGUI.

C函数的调用约定称为"cdecl".参数将被压入堆栈,并且在调用之后必须调整堆栈.如果将函数声明为PROTO C,则可以使用INVOKE让MASM完成该工作.

The calling conventions of C-functions is called "cdecl". The arguments are pushed onto the stack and the stack have to be adjusted after the call. You can let MASM do that job by using INVOKE, if you declare the function as PROTO C.

示例:

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文件中:

Let's add an output function to the C file:

抄送:

#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

这篇关于如何从我在MASM汇编器中调用的C函数中调用printf?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆