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

x86汇编(AT&T语法)递归斐波那契程序栈溢出问题排查

解决x86 AT&T汇编递归斐波那契的栈溢出问题

你的代码出现栈溢出引发的段错误,主要有两个核心问题,咱们一步步拆解分析:

1. 递归调用后未清理栈上的参数

你采用的是C调用约定(cdecl),这种规则下调用者必须负责清理传递给函数的栈参数。看你每次调用fibonacci前都会用push %ecx传递参数,但调用结束后完全没做栈清理操作——这意味着每一层递归都会在栈上残留4字节的无用数据,递归深度稍大就会直接把栈空间撑爆。

比如这段有问题的代码:

decl %ecx
push %ecx
call fibonacci
# 这里缺少清理栈参数的关键步骤!
movl %eax, fibMinus1(%esp)

每次调用完fibonacci后,必须执行addl $4, %esp,把刚才push的参数从栈上抹去,让栈指针恢复到调用前的位置。

2. 错误的栈帧寻址方式导致数据存错

你定义fibMinus1用来存储fib(n-1)的结果,但误用了%esp来寻址——%esp会随着push/pop操作不断变化,而栈帧的基址寄存器%ebp才是固定不变的,只有用它才能准确访问栈帧内的局部变量。

你当前的写法:

movl %eax, fibMinus1(%esp)

在push %ecx后,%esp已经比栈帧基址%ebp小了8字节(预留局部变量的4字节+push参数的4字节),此时fibMinus1(%esp)指向的根本不是你预留的局部变量位置,而是栈上的其他区域,会导致数据覆盖或读取错误,进一步加剧栈的混乱。

正确的写法应该是用%ebp寻址:

movl %eax, fibMinus1(%ebp)

因为fibMinus1定义为-4,对应栈帧基址%ebp偏移-4的位置,也就是你一开始sub $4, %esp预留的局部变量空间。

修复后的完整代码

# Function signature: 
# int fibonacci(int n)
.text
.equ n, 8                  # 参数n在ebp+8的位置
.equ fibMinus1, -4         # 局部变量fib(n-1)在ebp-4的位置
.global fibonacci
fibonacci:
    # Prologue (prepare the stack frame)
    push %ebp
    mov %esp, %ebp
    subl $4, %esp          # 提前为局部变量预留空间,栈帧结构更清晰
    
    # ECX存储参数n
    movl n(%ebp), %ecx
    
    # 如果n == 0,返回0
    cmpl $0, %ecx
    je retZero
    
    # 如果n == 1,返回1
    cmpl $1, %ecx
    je retOne
    
    # 计算fib(n-1)并保存到局部变量
    decl %ecx
    push %ecx
    call fibonacci
    addl $4, %esp          # 清理栈上的参数
    movl %eax, fibMinus1(%ebp)  # 用ebp寻址存储结果
    
    # 计算fib(n-2)
    movl n(%ebp), %ecx
    subl $2, %ecx
    push %ecx
    call fibonacci
    addl $4, %esp          # 清理栈上的参数
    
    # 结果 = fib(n-1) + fib(n-2)
    addl fibMinus1(%ebp), %eax
    
    # Epilogue
    mov %ebp, %esp
    pop %ebp
    ret

retZero:
    movl $0, %eax
    mov %ebp, %esp
    pop %ebp
    ret

retOne:
    movl $1, %eax
    mov %ebp, %esp
    pop %ebp
    ret

额外优化建议

  • 递归斐波那契本身时间复杂度是O(2^n),如果输入的n值过大,即便修复了栈问题也会因为递归层数太多导致性能极差,建议用迭代版本或者手动实现尾递归优化(x86不会自动做尾递归优化)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:40:24