考虑以下程序集(MASM)代码(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
它在Windows 7下编译好(在安装必要的开发工具并设置环境之后)并按预期运行:
$ ml64 helloworld.asm /link ucrt.lib vcruntime.lib msvcrt.lib /subsystem:console
[..]
$ helloworld.exe
hello world
但是,如果我在第1行和第10行的puts
中将printf
替换为helloworld.asm
,则链接器无法解析对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
作为奖励:如果我使用静态库文件libucrt.lib
,libvcruntime.lib
和libcmt.lib
,则可以使用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
这对我没有任何意义。我显然可以使用cl
编译一个使用动态库文件的C程序(通过指定/MD
标志),链接器解析printf
符号没有问题。
这里发生了什么以及如何解决?