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.
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?
My masm file:
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
My C.c file:
int greater(int a, int b) {
if ( a > b)
return a;
else
return b;
}
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.
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
.
Example:
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
Let's add an output function to the C file:
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;
}
Play with following batch file:
@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