很好奇x64微软fastcall实现中的返回地址存储在哪里。干杯。
和其他x86 x86-64的调用惯例一样,它在函数进入时的堆栈上,指向的是 rsp
. 拨打电话仍然使用 call
,它推送一个8字节的绝对返回地址并跳转到目标地址。
所以如果你运行一个 ret
指令,而RSP在输入时还有它的值,它将把该返回地址弹回RIP。 (ret
我们是这样写的 pop rip
在x86-64上)。) 如果你看一下编译器生成的代码,就会明白这一点,这些代码要么只是使用了 ret
,或者如果它在函数内部移动RSP,则在运行一个 ret
.
MS文档堆栈布局为其x64调用惯例。https:/docs.microsoft.comen-uscppbuildstack-usage?view=vs-2019。. 也是文件,用于 x64 __fastcall 一般来说。 (是的,MS确实称它为x64 __fastcall
即使它和x64 __vectorcall
是x86-64仅支持的2种调用约定。__fastcall
与32位稍有相似 __fastcall
但x64版本是调用者-pops堆栈,并且有更多的寄存器用于arg-pass。 而且xmm寄存器被调用保留的差异。 它确实使用了相同的前两个整数寄存器,虽然,因此我猜测的名称)。)
不管你的问题是什么,可能都不是这个。 虽然你在评论中提到了ESP。 如果你运行 sub esp, 8
在64位代码中,你会将RSP截断为32位,导致下次尝试pushpop或调用时出现故障。