x64 ms fastcall 中存储的 return 地址在哪里?
Where is the return address stored in x64 ms fastcall?
好奇 return 地址存储在 x64 Microsoft Fastcall 实现中的位置。干杯。
与所有其他 x86 / x86-64 调用约定相同,它位于函数入口的堆栈上,由 rsp
指向。仍然使用 call
进行调用,它压入一个 8 字节的绝对 return 地址并跳转到目标地址。
因此,如果您 运行 一个 ret
指令,而 RSP 具有它在入口时所做的值,它将将该 return 地址弹出回 RIP。 (ret
是我们在 x86-64 上编写 pop rip
的方式。)如果您查看编译器生成的仅使用 ret
的代码,或者如果它在函数内移动 RSP,这应该很清楚, 在 运行 宁 ret
.
之前再次恢复它
MS 文档针对其 x64 调用约定的堆栈布局。
https://docs.microsoft.com/en-us/cpp/build/stack-usage?view=vs-2019. Also docs for x64 __fastcall 一般。 (是的,MS 确实称它为 x64 __fastcall
,尽管它和 x64 __vectorcall
是它们支持 x86-64 的仅有的 2 个调用约定。x64 __fastcall
与 32-位 __fastcall
,但 x64 版本是调用者弹出堆栈,并有更多寄存器用于 arg 传递。xmm 寄存器的差异被调用保留。不过,它确实使用相同的前 2 个整数寄存器,因此我猜的名字。)
无论您的问题是什么,都可能不是这个问题。尽管您在评论中提到了 ESP。如果您在 64 位代码中 运行 sub esp, 8
,您将 运行 将 RSP 转换为 32 位,导致下次尝试 push/pop 或调用时出错。
好奇 return 地址存储在 x64 Microsoft Fastcall 实现中的位置。干杯。
与所有其他 x86 / x86-64 调用约定相同,它位于函数入口的堆栈上,由 rsp
指向。仍然使用 call
进行调用,它压入一个 8 字节的绝对 return 地址并跳转到目标地址。
因此,如果您 运行 一个 ret
指令,而 RSP 具有它在入口时所做的值,它将将该 return 地址弹出回 RIP。 (ret
是我们在 x86-64 上编写 pop rip
的方式。)如果您查看编译器生成的仅使用 ret
的代码,或者如果它在函数内移动 RSP,这应该很清楚, 在 运行 宁 ret
.
MS 文档针对其 x64 调用约定的堆栈布局。
https://docs.microsoft.com/en-us/cpp/build/stack-usage?view=vs-2019. Also docs for x64 __fastcall 一般。 (是的,MS 确实称它为 x64 __fastcall
,尽管它和 x64 __vectorcall
是它们支持 x86-64 的仅有的 2 个调用约定。x64 __fastcall
与 32-位 __fastcall
,但 x64 版本是调用者弹出堆栈,并有更多寄存器用于 arg 传递。xmm 寄存器的差异被调用保留。不过,它确实使用相同的前 2 个整数寄存器,因此我猜的名字。)
无论您的问题是什么,都可能不是这个问题。尽管您在评论中提到了 ESP。如果您在 64 位代码中 运行 sub esp, 8
,您将 运行 将 RSP 转换为 32 位,导致下次尝试 push/pop 或调用时出错。