如何将Windows通用CRT连接到使用nasm编译的obj文件
环境:Windows 10.我恰好在使用MinGW版本的ld
进行链接,但如果使事情变得更简单,我很乐意使用视觉工作室link.exe
。如何将Windows通用CRT连接到使用nasm编译的obj文件
,我有以下基本程序在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标准库的事实上的库。
感谢来自迈克尔·佩奇评论,它看起来像我需要手动链接1个或多个额外的库这是从ucrt.lib
库完全独立的位置。与printf相关的是legacy_stdio_definitions.lib
,我在我的VS2017安装目录的子目录中发现了深层,而在Windows SDK安装目录中的ucrt.lib
与此相反。
printf
的定义在stdio.h
直列设置除非宏_NO_CRT_STDIO_INLINE
被定义,这是我想这通常是VS工具链建筑物内时。
关于VS 2015+和缺乏一些符号被出口这对方的回答很可能与:http://*.com/questions/33721059/call-c-standard-library-function-from-asm-in -视觉工作室 。 MS重新编制了这些图书馆。 –
感谢您的链接。我尝试手动链接'legacy_stdio_definitions.lib'以及ucrt,它工作。传统的lib在一个完全不同的位置,虽然(我的vs2017安装目录)。没有在Windows sdk安装目录中的等效符号。有没有更好的方式将它与C标准库中可能需要的所有内容链接起来,还是我坚持每次指定这些子库? – Twicetimes
您需要将这些兼容性库与VS2015工具集包含在一起。但2013工具集没有重构的_C_库,所以你不会有这个问题。 –