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

为何程序.fini段会出现sub $0x8,%rsp与add $0x8,%rsp指令?

.fini段中sub $0x8,%rsp与add $0x8,%rsp操作的意义解析

问题背景

我反汇编的所有非库程序末尾都包含如下.fini段代码:

Disassembly of section .fini:

0000000000002f58 <.fini>:
    2f58:       f3 0f 1e fa             endbr64
    2f5c:       48 83 ec 08             sub    $0x8,%rsp
    2f60:       48 83 c4 08             add    $0x8,%rsp
    2f64:       c3                      ret

作为底层技术新手,我无法理解对%rsp先减0x8再加0x8的意义。我原以为这是类似Rust中saturating_sub的饱和减法,但实际并非如此,特此请教。

解答

这两个操作和饱和减法完全无关,核心是满足x86-64架构的栈对齐要求:

x86-64的System V ABI(类Unix系统通用的函数调用规范)明确要求:在执行函数调用(call指令)后,栈指针%rsp必须保持16字节对齐的状态。而ret指令执行时会从栈上弹出8字节的返回地址,相当于隐含执行了一次add $8,%rsp。

具体到这段.fini代码的执行逻辑:

  1. 当程序通过call指令进入.fini段时,%rsp指向的是压入栈的返回地址,此时%rsp是8字节偏移的状态——也就是未满足16字节对齐。
  2. sub $0x8,%rsp:将栈指针减8,把%rsp调整到16字节对齐的位置,确保后续代码(哪怕这段里没有显式函数调用)完全符合ABI规范,避免出现对齐错误导致的程序崩溃。
  3. add $0x8,%rsp:将栈指针加回8,恢复到进入.fini时的状态,这样执行ret指令弹出返回地址后,%rsp能回到正确的位置,不破坏程序整体的栈结构。

简单来说,这是编译器生成的通用代码模板,目的是保证栈始终符合架构的对齐规则,哪怕当前函数没有实际的栈操作,也要维持规范要求的栈状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:10:18