x64 Windows下VS编译代码栈空间疑问:sub rsp为何是48而非38?
x64下Visual Studio编译栈空间分配与偏移疑问解答
核心误解澄清
首先明确:汇编中的sub rsp,38和sub rsp,48是十六进制数值,对应十进制56和72,你之前误将其当作十进制计算,这是核心偏差的来源。
x64 Windows调用约定关键规则(VS默认__cdecl)
- 前4个整型/指针参数用RCX、RDX、R8、R9传递,调用者必须固定分配32字节(0x20)的影子空间,供被调用函数保存寄存器参数,与实际参数数量无关。
- 第5个及以后的参数,按从右到左顺序存在影子空间之后的栈上,且栈上参数/局部变量默认按8字节对齐分配(即使是4字节int)。
- 调用函数前,rsp必须是16字节对齐(call指令会压入8字节返回地址,确保被调用函数入口时rsp+8为16字节对齐)。
- VS默认启用/GS缓冲区安全检查,栈帧会额外分配8字节的GS cookie用于溢出检测。
func1栈空间(sub rsp,0x38=56字节)拆解
分配的栈空间包含:
- 8字节GS cookie
- 32字节影子空间
- 8字节局部变量p(4字节int按8字节对齐分配)
- 8字节对齐填充(满足调用前rsp为16字节对齐要求)
总大小:8+32+8+8=56(0x38),与汇编一致。
偏移rsp+0x20:影子空间(0x0~0x1F)结束后的第一个8字节对齐位置,用于存储局部变量p。
func2栈空间(sub rsp,0x48=72字节)拆解
分配的栈空间包含:
- 8字节GS cookie
- 32字节影子空间
- 8字节栈传递参数e(4字节int按8字节对齐分配)
- 8字节局部变量p(4字节int按8字节对齐分配)
- 16字节对齐填充(满足调用前rsp为16字节对齐要求)
总大小:8+32+8+8+16=72(0x48),与汇编一致。
偏移解释:
rsp+0x20:影子空间结束后的第一个8字节对齐位置,存储第5个参数e。rsp+0x30:参数e的8字节空间结束后,下一个8字节对齐位置,存储局部变量p。
你的计算逻辑问题
- 混淆了汇编中十六进制数值与十进制的区别,误将0x38当作十进制38计算。
- 错误加入了“return add 8字节”,这部分是call指令自动压入的返回地址,无需调用者提前分配。
- 未考虑VS默认启用的8字节GS cookie,以及栈上参数/局部变量的8字节对齐要求。
内容的提问来源于stack exchange,提问作者Soup Creamy Chicken
相关产品推荐
相关产品推荐

