Consider the following assembly (MASM) code (helloworld.asm
):
extern puts: PROC
.data
msg db 'hello world', 0Ah, 00
.code
main proc
sub rsp, 40
lea rcx, msg
call puts
add rsp, 40
ret
main endp
End
It compiles fine under Windows 7 (after installing the necessary development tools and setting up the environment) and behaves as expected:
$ ml64 helloworld.asm /link ucrt.lib vcruntime.lib msvcrt.lib /subsystem:console
[..]
$ helloworld.exe
hello world
However, if I replace puts
with printf
in helloworld.asm
on line 1 and line 10, the linker fails to resolve the reference to printf
:
$ ml64 helloworld.asm /link ucrt.lib vcruntime.lib msvcrt.lib /subsystem:console
[..]
helloworld.obj : error LNK2019: unresolved external symbol "printf" referenced in function "main".
helloworld.exe : fatal error LNK1120: 1 unresolved externals
As a bonus: If i use the static library files libucrt.lib
, libvcruntime.lib
and libcmt.lib
, it works with printf
:
$ ml64 helloworld.asm /link libucrt.lib libvcruntime.lib libcmt.lib /subsystem:console
Microsoft (R) Macro Assembler (x64) Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: helloworld.asm
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
/OUT:helloworld.exe
helloworld.obj
libucrt.lib
libvcruntime.lib
libcmt.lib
/subsystem:console
$ helloworld.exe
hello world
This does not make any sense to me. I can obviously compile a C-program with cl
which uses the dynamic library files (by specifying the /MD
flag) and the linker has no problems resolving the printf
symbol.
What is happening here and how can it be solved?