x64 程序集中的 'shadow space' 是什么?

What is the 'shadow space' in x64 assembly?

我找到了很多关于这个影子的话题 space,但是我在 none 中找不到答案,所以我的问题是:

在进入过程之前,我需要从堆栈指针中减去多少字节?

我应该在减去 "shadow space" 之前将过程参数压入堆栈吗?

我已经反汇编了我的代码,但找不到逻辑。

影子space 是您必须为被调用过程保留的强制性32 字节(4x8 字节)。这只是意味着您必须在调用之前在堆栈上提供 32 个字节。这个space可以不初始化,没关系

请注意,在 x64 调用约定中,第 4 个之后的参数被压入堆栈,位于此影子的顶部 space(压入 32 字节之前)。

简而言之,您可以将其视为 x64 中的函数至少有 4 个参数,但寄存器中第 4 个的值。

调用 x64 时还应考虑堆栈对齐等问题。

Shadow space(有时也称为Spill spaceHomespace) 比被调用函数拥有的 return 地址高 32 个字节(并且可以用作 scratch space),如果有的话在堆栈参数之下。调用者必须在 运行 一条 call 指令之前为其被调用者的影子 space 保留 space。

它旨在用于简化 x64 调试。

回想一下first 4 parameters are passed in registers。如果您进入调试器并检查线程的调用堆栈,您将看不到传递给函数的任何参数。存储在寄存器中的值是瞬态的,在向上移动调用堆栈时无法重建。

这就是 Home space 发挥作用的地方:编译器可以使用它在堆栈上保留寄存器值的副本,以便以后在调试器。这通常发生在未优化的构建中。但是,当启用优化时,编译器通常会将 Home space 视为可供临时使用。堆栈上没有留下任何副本,调试故障转储变成了一场噩梦。

Challenges of Debugging Optimized x64 Code 提供有关该问题的深入信息。