环境:Windows 10.我碰巧使用MinGW版本的ld
进行链接,但如果它让事情变得更简单,我很乐意使用visual studio link.exe
。
我在nasm中有以下基本程序:
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
使用
构建它nasm -f win32 test.nasm
尝试将其链接到Windows CRT(ucrt.lib)时,出现以下错误:
$ ld -o test.exe test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
好的,所以我需要将链接器指向ucrt库:
$ ld -o test.exe /c/Program\ Files\ \(x86\)/Windows\
Kits/10/Lib/10.0.14393.0/ucrt/x86/ucrt.lib test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
尝试使用visual studio链接器的等价物:
d:\Code\nasm>link -out:test.exe -entry:main -subsystem:console test.obj
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation. All rights reserved.
test.obj : error LNK2001: unresolved external symbol _printf
test.exe : fatal error LNK1120: 1 unresolved externals
这提出了几个问题:
为什么其中一个尝试查找printf
而另一个_printf
?我知道那里有一个下划线约定,但两个链接器似乎都没有理解它。
我使用objdump -t
来查看ucrt.lib文件中的符号。我不会粘贴整个列表,但它包含以下条目:
[ 4](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp____conio_common_vcprintf
[ 5](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ___conio_common_vcprintf
[ 4](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp____conio_common_vcprintf_p
列表中不会出现printf
和_printf
。这是否意味着它不会被该库导出?如果没有,我应该链接哪个库?
根据this MS article,ucrt.lib
是c运行时和C标准库的事实上的库。
答案 0 :(得分:1)
感谢Michael Petch的评论,看起来我需要手动链接一个或多个额外的库,这些库位于与ucrt.lib
库完全不同的位置。 printf的相关内容是legacy_stdio_definitions.lib
,我在VS2017安装目录的子目录深处找到了它,而不是Windows SDK安装目录中的ucrt.lib
。
printf
的定义是stdio.h
内联提供的,除非定义了宏_NO_CRT_STDIO_INLINE
,我想这通常是在VS工具链内构建时。