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

在WSL的x86-64汇编中调用printf触发段错误,求原因

x86-64汇编代码触发段错误的原因分析

问题描述

以下是编写的x86-64汇编代码:

.intel_syntax noprefix

            .data
b:          .byte 9
s:          .word 0
l:          .long 0
q:          .quad 0
format:     .asciz "%s"
text:       .asciz "Hello world!"

            .text
            .global main
main:   
            push rbx /* stack needs to be 16 bytes aligned */
            mov rdi, format /* first argument to printf */
            mov rsi, text /* second argument to printf */
            mov rax, 0 /* no parameters in a vector register */
            call printf
            pop rbx /* restore stack pointer */
            ret

运行环境:Windows 11 + WSL
编译命令:gcc -g -no-pie -O0 -o sandbox.elf ./sandbox.s
运行命令:./sandbox.elf
运行结果:Segmentation fault

疑问:代码遵循了System V ABI规范,为何会触发段错误?

错误原因及解决方法

问题出在栈对齐上。System V AMD64 ABI明确要求:在执行call指令调用函数之前,栈指针rsp必须保持16字节对齐。

当程序进入main函数时,rsp指向的是调用main时被压入栈的返回地址(8字节),此时rsp的地址是16N + 8,本身就未满足16字节对齐。你代码中push rbx(8字节)后,rsp变为16N,看似对齐,但执行call printf时,call指令会自动将返回地址(8字节)压入栈,导致rsp变成16N - 8,直接破坏了对齐要求——printf内部依赖对齐的栈进行内存操作,最终触发段错误。

修正方案

只需在push rbx后额外调整8字节栈空间,确保调用printf前rsp处于16字节对齐状态即可,以下两种方式都可行:

方式1:直接调整栈空间

.intel_syntax noprefix

            .data
b:          .byte 9
s:          .word 0
l:          .long 0
q:          .quad 0
format:     .asciz "%s"
text:       .asciz "Hello world!"

            .text
            .global main
main:   
            push rbx 
            sub rsp, 8  /* 额外调整8字节,确保调用printf前rsp对齐 */
            mov rdi, format
            mov rsi, text
            mov rax, 0
            call printf
            add rsp, 8  /* 恢复栈空间 */
            pop rbx
            ret

方式2:建立栈帧

.intel_syntax noprefix

            .data
b:          .byte 9
s:          .word 0
l:          .long 0
q:          .quad 0
format:     .asciz "%s"
text:       .asciz "Hello world!"

            .text
            .global main
main:
            push rbp
            mov rbp, rsp  /* 建立栈帧,自动满足栈对齐要求 */
            mov rdi, format
            mov rsi, text
            mov rax, 0
            call printf
            pop rbp
            ret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:55:01