首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在godbolt.org上使用NASM程序集调用printf()?

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

Stack Overflow用户
提问于 2022-07-26 15:53:40
回答 1查看 193关注 0票数 1

试图在https://godbolt.org/z/G66bdzoof上运行linux (),但它返回了以下错误:

ASM生成编译器返回:0 /usr/bin/ld: /app/example.o: /app/example.o:/app/example.asm:14:未定义的对“`printf”执行构建编译器的引用返回:1

代码语言:javascript
复制
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

问题

是否缺少某种编译器选项?

哥德波特例子正在使用以下编译选项:

代码语言:javascript
复制
-g -f elf -F stabs /tmp/compiler-explorer-compiler2022626-8227-fdi87r.9yqas/example.asm
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-26 16:16:46

问题不在组装,NASM执行得很好。问题是与ld的链接。编译器资源管理器构建是链接到一个没有库的静态可执行文件,大概只有ld -m elf_i386 -o foo foo.o

编译器资源管理器UI只允许您控制nasm选项,而不是ld选项,因此不能通过-lc链接C库。如果你在戈德螺栓上使用“库”下拉列表,它会说“没有为这种语言配置任何库”。(与C++相比,还有像Google::Benchmark这样的库,您可以添加告诉它链接;有些库不是头库--仅限于头,因此必须实际生成链接器选项)。

无论如何,您都希望使用调试器来单步执行代码,所以在本地安装一个dev安装程序。https://www.onlinegdb.com/有组装支持,但只有GCC (所以气体语法,AT&T或英特尔,但不符合纳斯达克指令)。

是的,使用调试器基本上是必不可少的。没有这些,你只是在浪费你自己的时间(如果你让其他人花时间看代码,你自己还没有一步一步)。就像试图制造一个蒙着眼睛的机器人。有关Linux或Windows的asm调试技巧,请参见x86标记wiki的底部。(您的当前程序只在Linux上工作;它使用32位int 0x80系统调用ABI退出。)

通常,如果使用C库函数,则需要编写main;如果使用printf之类的stdio函数,则不要使用原始_exit系统调用。当输出到管道或网络套接字(不是终端)时,stdout将被完全缓冲,而不是行缓冲,因此当您不调用fflush时,您将没有输出。

但是,即使编写自己的_start (跳过CRT启动代码),如果动态链接而不是静态链接,与libc的链接也会工作。Linux上的glibc有动态链接器挂钩,允许它在_start运行之前初始化自己(与其他一些系统不同,比如cygwin),但是如果静态链接,那么_start确实是在用户空间中运行的第一个指令。调用依赖于全局stdout等数据结构的printf之类的函数将崩溃。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73126416

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档