x86 Windows调用约定下函数参数相对于%rbp的偏移位置求解
核心遗漏要点
你主要漏了Windows x64调用约定的两个强制规则,以及rbp的固定指向特性:
- 32字节影子空间预留:Windows x64约定调用方必须为被调用方的前4个寄存器参数预留32字节的栈空间,这部分空间在调用方执行
call指令前就已经分配完成,属于固定的栈帧部分,哪怕参数用寄存器传递,这部分空间也会存在。 - 第5个寄存器参数的栈预留槽:题目约定前5个参数通过寄存器传递,因此除了前4个参数的32字节影子空间,调用方还会为第5个参数
e预留8字节的栈槽位。 - rbp的值在函数 prologue 执行完成后固定不变:函数开头执行完
pushq %rbp; movq %rsp, %rbp之后,rbp就固定指向当前栈顶存储旧rbp的位置,后续subq $32, %rsp分配本地变量空间只会修改rsp,不会影响rbp的指向,因此参数偏移计算完全基于固定的rbp,和rsp的后续变化无关。
栈布局推导(偏移为相对于rbp的值,地址从低到高排序)
| 存储内容 | 偏移范围 | 大小 |
|---|---|---|
| 旧rbp值 | 0 ~ +7 | 8字节 |
| 调用方返回地址 | +8 ~ +15 | 8字节 |
| 前4个参数的32字节影子空间 | +16 ~ +47 | 32字节 |
| 参数e预留槽 | +48 ~ +55 | 8字节 |
| 参数f(调用方压入) | +56 ~ +63 | 8字节 |
| 参数g(调用方压入) | +64 ~ +71 | 8字节 |
| 参数h(调用方压入) | +72 ~ +79 | 8字节 |
| 参数i(调用方压入) | +80 ~ +87 | 8字节 |
完全匹配教授给出的偏移结果:
- e 对应
%rbp + 48 - f 对应
%rbp + 56 - g 对应
%rbp + 64 - h 对应
%rbp + 72 - i 对应
%rbp + 80
内容的提问来源于stack exchange,提问作者compcomp
相关产品推荐
相关产品推荐

