简体   繁体   English

如何在 godbolt.org 上使用 NASM 程序集调用 printf()?

[英]How to call printf() using NASM assembly on godbolt.org?

Trying to run linux NASM printf() on https://godbolt.org/z/G66bdzoof , but it's returning this error:尝试在https://godbolt.org/z/G66bdzoof上运行 linux NASM printf() ,但它返回此错误:

ASM generation compiler returned: 0 /usr/bin/ld: /app/example.o:/app/example.asm:14: undefined reference to `printf' Execution build compiler returned: 1 ASM 生成编译器返回:0 /usr/bin/ld: /app/example.o:/app/example.asm:14: undefined reference to `printf' 执行构建编译器返回:1

extern printf

global _start

section .data
    message db "Hello World!", 10, 0

section .text

_start:

    ; print message
    push dword message
    call printf 
    add esp, 4 

    ; exit with code 0
    mov eax,1
    mov ebx,0
    int 80h

Question问题

Are there some kind of compiler options missing?是否缺少某种编译器选项?

The godbolt example is using these compilation options: Godbolt 示例使用以下编译选项:

-g -f elf -F stabs /tmp/compiler-explorer-compiler2022626-8227-fdi87r.9yqas/example.asm

The problem isn't assembling, NASM executes fine.问题不在于组装,NASM 执行良好。 The problem is linking , with ld .问题是与ld链接 The Compiler Explorer build is linking into a static executable without libraries, presumably just ld -m elf_i386 -o foo foo.o编译器资源管理器构建链接到没有库的 static 可执行文件,大概只是ld -m elf_i386 -o foo foo.o

The Compiler Explorer UI only gives you control over nasm options, not ld options, so you can't pass -lc to link the C library. Compiler Explorer UI 只能让您控制nasm选项,而不是ld选项,因此您不能通过-lc链接 C 库。 If you use the "library' dropdown on Godbolt, it says "no libraries are configured for this language". (vs. for C++, there are libs like Google::Benchmark you can add tell it to link with; some of the libraries are not header-only, so must actually generate linker options).如果您使用 Godbolt 上的“库”下拉菜单,它会显示“没有为此语言配置库”。(与 C++ 相比,您可以添加诸如 Google::Benchmark 之类的库,告诉它链接;一些库不是仅标题,因此必须实际生成 linker 选项)。


You're going to want to use a debugger to single-step your code anyway, so install a dev setup locally.无论如何,您都将希望使用调试器来单步执行您的代码,因此请在本地安装开发设置。 https://www.onlinegdb.com/ has assembly support, but only GCC (so GAS syntax, AT&T or Intel but not with NASM directives). https://www.onlinegdb.com/具有汇编支持,但仅支持 GCC(因此 GAS 语法,AT&T 或 Intel,但不支持 NASM 指令)。

And yes, using a debugger is basically essential.是的,使用调试器基本上是必不可少的。 Without that you're just wasting your own time (and everyone else's if you ask other people to spend time looking at code you haven't single-stepped yourself).否则,您只是在浪费自己的时间(如果您要求其他人花时间查看您自己没有单步执行的代码,那么其他人也是如此)。 It's like trying to build a robot blindfolded.这就像试图制造一个蒙着眼睛的机器人。 See the bottom of the x86 tag wiki for asm debugging tips for Linux or Windows.有关 Linux 或 Windows 的 asm 调试技巧,请参阅x86 标签 wiki的底部。 (Your current program will only work on Linux; it uses the 32-bit int 0x80 system-call ABI to exit.) (您当前的程序只能在 Linux 上运行;它使用 32 位int 0x80系统调用 ABI 退出。)


Normally you'd want to write a main if you're using C library functions, and don't use a raw _exit system-call if using stdio functions like printf.通常,如果您使用 C 库函数,您会想要编写一个main ,并且如果使用像 printf 这样的 stdio 函数,则不要使用原始的_exit系统调用。 With output to a pipe or network socket (not a terminal), stdout will be full-buffered not line-buffered, so you'll get no output when you _exit without calling fflush.使用 output 到 pipe 或网络套接字(不是终端),stdout 将是全缓冲而不是行缓冲,所以当你调用_exit时你不会得到 Z78E6221F6393D1356681DB_exDZ.

But linking with libc will work even when you write your own _start (skipping the CRT startup code), if you dynamically link, not static.但是,即使您编写自己的_start (跳过 CRT 启动代码),与 libc 的链接也可以工作,如果您动态链接,而不是 static。 glibc on Linux has dynamic linker hooks that let it initialize itself before _start runs (unlike on some other systems, eg cygwin), but if you statically link then your _start is truly the first instructions that run in user-space. Linux 上的 glibc 具有动态 linker 钩子,可以让它在_start运行之前自行初始化(与其他一些系统不同,例如 cygwin),但是如果您静态链接,那么您的_start确实是在用户空间中运行的第一条指令。 Calling functions like printf that depend on data structures like global stdout will crash.调用 printf 等依赖于全局stdout等数据结构的函数将崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM