You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Godbolt.org用NASM调用printf报错,是否缺少编译选项?

问题解决:NASM汇编调用printf出现未定义引用错误

错误原因

printf是C标准库提供的函数,你的汇编代码仅声明了它是外部符号,但链接阶段没有告知链接器去C标准库中查找该符号,因此触发"未定义引用"错误。此外,直接使用_start作为入口并调用libc函数时,会跳过libc的初始化流程,可能导致函数无法正常工作。

解决方法

方法1:改用main作为入口,通过GCC编译链接(推荐)

GCC会自动处理C标准库的链接和初始化,无需手动配置:

  1. 修改汇编代码,将入口点改为main,并遵循C调用约定:
extern printf

global main

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

section .text

main:
    ; 建立栈帧(符合C调用约定)
    push ebp
    mov ebp, esp

    ; 调用printf
    push dword message
    call printf
    add esp, 4  ; 清理栈上的参数

    ; 返回0给操作系统
    mov eax, 0
    leave
    ret
  1. 在Godbolt中选择x86 GCC作为编译器,编译选项填写:
-g -m32

GCC会自动调用NASM汇编代码,并链接C标准库,完成编译运行。

方法2:保留_start入口,手动链接C标准库

如果坚持使用_start,需要手动链接libc,同时调用libc的初始化和清理函数(否则printf可能无法正常输出):

  1. 修改汇编代码,添加libc初始化和清理逻辑:
extern printf
extern __libc_start_main
extern exit

global _start

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

section .text

_start:
    ; 调用libc初始化,传入main函数地址等参数
    push dword 0          ; 环境变量指针
    push dword 0          ; argc
    push dword main       ; 自定义main函数地址
    call __libc_start_main

main:
    push dword message
    call printf
    add esp, 4

    ; 调用libc的exit函数退出
    push dword 0
    call exit
  1. 在Godbolt中选择NASM作为编译器,编译选项填写:
-g -f elf32

链接选项填写:

-lc -m32

(-lc表示链接C标准库,-m32指定生成32位程序)

原编译选项的问题

原选项-g -f elf -F stabs仅完成了汇编步骤,未包含链接C标准库的配置;且-F stabs是老旧的调试格式,现代环境无需指定,-g已足够生成调试信息。

内容的提问来源于stack exchange,提问作者vengy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 02:54:24