【问题标题】:fastcall: What happens with the stack?fastcall:堆栈会发生什么?
【发布时间】:2014-02-24 15:29:48
【问题描述】:

我目前正在自学 x64 汇编,但无法理解从 c++ 调用汇编过程时堆栈会发生什么。

根据我目前对MSDNIntel 的了解,前 4 个整数/浮点参数存储在 rcx/xmm0、rdx/xmm1、r8/xmm2 和 r9/xmm3 寄存器中,所有其他参数将是放在堆栈上。

我只是不明白为什么我必须从 rsp [rsp+28h] 访问第 5 个参数 40 个字节而不是 8 个,因为前 32 个字节是在寄存器中访问的。

谁能解释一下到底发生了什么?

谢谢。

【问题讨论】:

  • 谈论“fastcall”在 64 位代码中没有意义。调用约定的一部分是“影子空间”,堆栈帧中的额外空间可以在必要时存储 RCX、RDX、R8 和 R9。
  • @HansPassant:但无论如何,微软和英特尔都在谈论它,以强调 x64 调用约定更类似于 fastcall,而不是 Windows 在 x86 上使用的任何其他调用约定。

标签: stack 64-bit parameter-passing fastcall


【解决方案1】:

关键在于链接的 MSDN 中的这个短语:

x64 应用程序二进制接口 (ABI) 是一个 4 个寄存器的快速调用调用约定,为这些寄存器提供堆栈支持

也就是说,寄存器加载了前 4 个参数,但它们在堆栈中保留了空间。正如@HansPassant 在下面的 cmets 中指出的那样,调用者不会写入此 shadow 空间,但它可供被调用者使用,如果它需要保存寄存器(例如用于调用另一个函数)。

【讨论】:

  • “仍然存储在堆栈中”相当具有误导性。只有当被调用函数需要保留参数值时才会发生这种情况,因为它想将寄存器用于更好的事情。理想情况下,这永远不会发生。
  • @HansPassant:啊,所以调用者分配了这个影子空间,但没有写入它,它仅供被调用者使用?我正在编辑我的答案。
  • 谢谢你们的澄清:)
猜你喜欢
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多