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

为何x86汇编中函数调用的第一个参数对应rbp-4而非rbp+4?

函数栈帧参数地址疑问解答

示例代码

C++ 实现

int square(int num, int i2) {
    return num * num;
}

对应汇编代码

square(int, int):
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     DWORD PTR [rbp-8], esi
        mov     eax, DWORD PTR [rbp-4]
        imul    eax, eax
        pop     rbp
        ret

问题解释

你疑惑的核心原因在于这段汇编采用了x86-64架构的System V调用约定,参数并非一开始就存在栈上,而是先通过寄存器传递,之后被拷贝到当前函数的局部栈帧里。

你之前了解的「参数→返回地址→旧ebp」是32位x86传统调用约定(比如cdecl)的栈布局,这种场景下参数会被调用者压入栈,函数内访问参数时确实会用rbp+4、rbp+8这类偏移(因为旧ebp在rbp位置,上方是返回地址和参数,栈向低地址增长,所以参数在高地址侧)。

但在64位的System V调用约定中,前6个整数/指针参数是通过寄存器传递的:第一个参数存在rdi,第二个在rsi,以此类推。这段汇编里的mov DWORD PTR [rbp-4], edi就是把第一个参数从edi寄存器里复制到当前函数栈帧的局部变量区域——rbp是当前栈帧的基址,栈向低地址增长,所以局部变量区域在rbp的下方,用rbp-4、rbp-8这样的偏移。

简单说,你看到的rbp-4不是原参数的地址,而是参数值被拷贝后存在当前函数局部栈里的地址,原参数根本没在栈上(而是一开始在寄存器里)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:12:16