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

时间:2017-04-05 18:41:09

标签: linker nasm crt universal-crt

环境: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

这提出了几个问题:

  1. 为什么其中一个尝试查找printf而另一个_printf?我知道那里有一个下划线约定,但两个链接器似乎都没有理解它。

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

  3. [ 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 articleucrt.lib是c运行时和C标准库的事实上的库。

1 个答案:

答案 0 :(得分:1)

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

printf的定义是stdio.h内联提供的,除非定义了宏_NO_CRT_STDIO_INLINE,我想这通常是在VS工具链内构建时。