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

Ubuntu下Intel x64汇编调用printf出现段错误求助

x64汇编printf调用段错误的解决方案

问题描述

编写Intel x64架构汇编程序,在Ubuntu系统中通过nasm编译、gcc链接后运行出现段错误,经排查问题出在printf函数调用处,预期输出指定消息失败,GDB调试未获取有效线索。相关代码及Makefile如下:

原汇编代码(hello3.asm)

;hello3.asm
;27/06/2024
extern printf

section .data
        msg db "this is a message", 0
        fmtstr db "%s", 0
section .bss
section .text
        global main
main:
        mov rdi, fmtstr
        mov rsi, msg
        mov rax, 0
        call printf

        mov rax, 60
        mov rdi, 0
        syscall

原Makefile内容

hello3:hello3.o
        gcc -o hello3 hello3.o --no-pie -no-pie
hello3.o:hello3.asm
        nasm -f elf64 -o hello3.o -l hello3.lst -g -F dwarf hello3.asm

问题原因

  1. 栈对齐不符合ABI要求:x86-64 System V ABI规定,调用函数前栈指针rsp必须保持16字节对齐。main被调用时,栈上已压入8字节的返回地址,此时rsp未对齐,直接调用printf会触发段错误。
  2. 直接使用系统调用退出未清理C库环境:printf属于C标准库函数,调用后直接用syscall执行退出操作,会跳过C库的运行时清理流程,引发未定义行为。

修复方案

修改汇编代码,调整栈对齐并改用C标准库的exit函数退出:

;hello3.asm
;27/06/2024
extern printf
extern exit

section .data
        msg db "this is a message", 0
        fmtstr db "%s", 0
section .bss
section .text
        global main
main:
        sub rsp, 8          ; 调整栈指针至16字节对齐
        mov rdi, fmtstr
        mov rsi, msg
        mov rax, 0
        call printf
        add rsp, 8          ; 恢复栈指针

        mov rdi, 0          ; 设置退出码为0
        call exit           ; 调用C库exit函数完成清理并退出

验证步骤

执行以下命令重新编译运行:

make clean
make
./hello3

程序将正常输出this is a message,无段错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 12:42:43