2

环境: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 文件中的符号。我不会粘贴整个列表,但它包含以下条目:

[ 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 标准库的事实上的库。

4

1 回答 1

2

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

除非定义了宏,否则定义printf是内联的,我猜这通常是在 VS 工具链中构建时。stdio.h_NO_CRT_STDIO_INLINE

于 2017-04-05T19:17:02.403 回答