Reputation: 11
So I'm new to this low-level programming and I'm trying to call the stdio.h function printf() in my assembly source file, that is linked to my C++ source file.
64-bit MASM file:
option casemap:none
.data
string byte 'Hello Biss',10,0
.code
externdef printf:proc
public asmFunc
asmFunc proc
sub rsp,56
lea rcx, string
call printf
add rsp,56
ret
asmFunc endp
end
my asmFunc is being called by a C++ program:
#include <stdio.h>
extern "C"
{
void asmFunc();
};
int main()
{
printf("some text\n");
asmFunc();
}
The problem is, that the code only works if I already call the print() function somewhere else in the C++ source file (see above). As soon as I delete the <printf("some text\n");> line, I get a Linking error in Visual Studio:
I assume the linker doesn't see the stdio.h file being used in my C++ source file and tries to optimize it by excluding this line(?).
Now I could obviously just solve this by using the printf() somewhere in the code, but as I'm trying to write this test code as efficiently as possible, this doesn't seem optimal...
Any advice on what is the best way to handle this?
Upvotes: 0
Views: 431
Reputation: 180205
I assume the linker doesn't see the stdio.h file being used in my C++ source file
Correct. That's an #include
. This is processed by the preprocessor. It inserts a bunch of function declarations such as printf
and scanf
into your Translation Unit. The function definitions are somewhere else, that's the job of the linker.
and tries to optimize it by excluding this line(?).
Incorrect. The linker simply has no work to do. Neither printf
nor scanf
is used by your C++ Translation Unit.
The true problem appears to be that MASM does not tell the linker that it needs printf
to be linked to the executable. Assembly is of course a very primitive language; you basically ask the linker to insert the address of the printf
function. That assumes that the printf
function is already part of your executable, whih in turns implies that somebody else asked to include printf
.
Usually, this is not a problem, because assembly is rarely used, when it's used it doesn't call out to non-assembly code, and when it does call out, it calls back to your own C or C++ functions. And the functions in your .cpp file are included by the linker because they're in your own .cpp files. printf
has to come from a library, which works differently.
If MASM doesn't tell the linker what it needs, you can do it directly. /INCLUDE:printf
tells the linker to add printf
, even if no Translation Unit asked for it.
Upvotes: 1