环境: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
出现在列表中。这是否意味着它不是由该库导出的?如果没有,我应该链接哪个库?
根据这篇 MS 文章,ucrt.lib
是 c 运行时和 C 标准库的事实上的库。