Linker 如何将Windows通用CRT链接到用nasm编译的obj文件

Linker 如何将Windows通用CRT链接到用nasm编译的obj文件,linker,nasm,crt,universal-crt,Linker,Nasm,Crt,Universal Crt,环境:Windows10。我碰巧使用了MinGW版本的ld进行链接,但是如果visual studiolink.exe使事情变得更简单,我很乐意使用它 我在nasm中有以下基本程序: global _main extern _printf section .text _main: push message call _printf add esp, 4 ret message: db 'Hello, Wo

环境:Windows10。我碰巧使用了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
    ,而另一个要查找
    \u printf
    ?我知道有一个下划线约定,但两个链接器似乎都不理解

  • 我使用
    objdump-t
    查看ucrt.lib文件中的符号。我不会粘贴整个列表,但它包含以下条目:

  • [4](第1节)(fl 0x00)(ty 0)(scl 2)(nx 0)0x00000000\uuuuuuuuuuuuuuuuuuuuuu conio\uvcprintf

    [5](第3节)(fl 0x00)(ty 0)(scl 2)(nx 0)0x00000000

    [4](第1节)(fl 0x00)(ty 0)(scl 2)(nx 0)0x00000000\uuuuuuuuuuuuuuuuuuuuuu conio\uuvcPrintf\uP

    列表中既不显示
    printf
    也不显示
    \u printf
    。这是否意味着它不是由该库导出的?如果没有,我应该链接哪个库


    根据,
    ucrt.lib
    是c运行时和c标准库的事实库。

    感谢Michael Petch的评论,看起来我需要手动链接一个或多个额外的库,这些库与
    ucrt.lib
    库位于完全不同的位置。printf的相关版本是
    legacy_stdio_definitions.lib
    ,我在VS2017安装目录的子目录中找到了它,而不是Windows SDK安装目录中的
    ucrt.lib


    printf
    的定义在
    stdio.h
    中内联提供,除非定义了宏
    \u NO\u CRT\u stdio\u inline
    ,我猜这通常是在VS工具链内部构建时定义的。

    关于VS 2015+和缺少导出的一些符号,这另一个答案可能是相关的:。微软修改了图书馆。谢谢你的链接。我尝试手动链接
    legacy\u stdio\u definitions.lib
    以及ucrt,结果成功了。但是,旧库位于完全不同的位置(我的vs2017安装目录)。windows sdk安装目录中没有等效项的迹象。是否有更好的方法将此链接到我可能需要的C标准库中的所有内容,或者我每次都必须指定这些子库?您需要将这些兼容性库包括在VS2015工具集中。然而,2013工具集没有重构的C库,所以你不会有这个问题。好的,谢谢你的帮助。如果你想把它作为正式的回答,我会接受的。如果你愿意,你可以在这里回答你自己的问题。