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

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。

你的计算逻辑问题

  1. 混淆了汇编中十六进制数值与十进制的区别,误将0x38当作十进制38计算。
  2. 错误加入了“return add 8字节”,这部分是call指令自动压入的返回地址,无需调用者提前分配。
  3. 未考虑VS默认启用的8字节GS cookie,以及栈上参数/局部变量的8字节对齐要求。

内容的提问来源于stack exchange,提问作者Soup Creamy Chicken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:03:11