如何将Windows通用CRT链接到使用nasm编译的obj文件 [英] How to link Windows universal CRT to obj file compiled with nasm

查看:64
本文介绍了如何将Windows通用CRT链接到使用nasm编译的obj文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

环境:Windows10.我碰巧正在使用MinGW版本的 ld 进行链接,但是如果使用Visual Studio link.exe ,我很高兴.使事情变得更简单.

Environment: Windows 10. I happen to be using a MinGW version of ld for linking, but I'm happy to use the visual studio link.exe if it makes things simpler.

我在nasm中有以下基本程序:

I have the following basic program in 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)时,出现以下错误:

When trying to link it to the windows CRT (ucrt.lib), I get the following error:

$ ld -o test.exe test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'

好,所以我需要将链接器指向ucrt库:

Ok, so I need to point the linker at the ucrt library:

$ 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链接器进行等效操作:

Trying the equivalent with the visual studio linker:

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 ?我知道有一个下划线约定,但似乎两个链接器都不理解.

  1. Why does one of these try to find printf and the other, _printf? I get that there's an underscore convention, but it doesn't seem to be understood by both linkers.

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

I used objdump -t to look at the symbols in the ucrt.lib file. I won't paste the entire list, but it contains entries such as:

[4](秒1)(fl 0x00)(ty 0)(scl 2)(nx 0)0x00000000 __imp ____ conio_common_vcprintf

[5](秒3)(fl 0x00)(ty 0)(scl 2)(nx 0)0x00000000 ___ conio_common_vcprintf

[4](秒1)(fl 0x00)(ty 0)(scl 2)(nx 0)0x00000000 __imp ____ conio_common_vcprintf_p

printf_printf 都没有出现在列表中.这是否意味着该库未导出该文件?如果没有,我应该链接哪个库?

Neither printf nor _printf appears in the list. Does this mean it's not exported by that library? If not, which library should I be linking?

根据这篇MS文章 ucrt.lib 是c运行时和C标准库的事实上的库.

According to this MS article, ucrt.lib is the de-facto library for the c runtime and C standard library.

推荐答案

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

Thanks to a comment from Michael Petch, it looks like I need to manually link 1 or more extra libs which are in a completely separate location from the ucrt.lib library. The relevant one for printf is legacy_stdio_definitions.lib, which I found deep in a sub-dir of my VS2017 install directory, as opposed to the ucrt.lib which is in the Windows SDK install directory.

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

The definition of printf is provided inline in stdio.h unless the macro _NO_CRT_STDIO_INLINE is defined, which I guess it usually is when building inside the VS toolchain.

这篇关于如何将Windows通用CRT链接到使用nasm编译的obj文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆