Eva*_*oll 10 windows assembly stack x86-64 calling-convention
在Kip Irvine 的《Assembly Language, Seventh Edition for x86 Processors》第 211 页中,它在5.53 The x86 Calling Convention下说,它解决了 Microsoft x64 Calling Convention,
- 调用子程序时,堆栈指针 (
RSP
) 必须在 16 字节边界(16 的倍数)上对齐。该CALL
指令将 8 字节返回地址压入堆栈,因此调用程序除了已经为影子空间减去 32 之外,还必须从堆栈指针中减去 8 。
它继续显示一些sub rsp, 8
在 之前带有 的程序集sub rsp, 20h
(对于 32 字节的影子空间)。
但这是一个安全的约定吗?Microsoft 堆栈是否保证在指令之前按 16 字节对齐CALL
?或者,这本书假设堆栈是错误的
CALL
CALL
sub rsp, 8;
才能恢复到 16 字节对齐吗?我询问如何满足 x64 ABI 的要求。每次调用后通过将堆栈增加 8 个字节以实现 16 字节对齐来盲目调整堆栈是否安全?
是的,这就是 ABI 要求/保证call
.
您可以在函数内执行任何操作,例如 3x 16 位压入,然后sub rsp, (24 - 3*2)
在进入函数后重新获得 16 字节堆栈对齐。
或者movq xmm0, rsp
然后用作rsp
额外的暂存寄存器以获得总共 16 个整数寄存器,直到您在创建另一个call
或之前恢复它ret
。1
不要求 RSP 在每条指令后都 16 字节对齐,仅在函数调用边界处。 这就是为什么它们被称为“调用约定”,而不是“编码标准”。
这与调用保留的 rbx 类似。如果您将其保存/恢复到堆栈中、xmm0 中、静态存储中,如果您对它取反然后再次对它取反,或者如果您根本不碰它,都没有关系。重要的是,当您返回到调用者时,它的值与调用函数时的值相同。
脚注 1:只要您没有任何可能在用户空间堆栈上运行的异步回调/SEH 处理程序,就可以工作。这并不能真正保证安全,但可能会起到黑客作用。
下面写ESP有效吗?相关的是:正如 Ped7g 指出的那样,如果某些东西可以异步使用堆栈指针下方的空间,那么如果 RSP 根本不指向堆栈内存,它可能会中断。
我见过一个 32 位的 avisynth 视频过滤器示例(我认为),它使用它来获取 8 个 tmp 寄存器(当没有 MMX 可用时),在代码中包含大量警告注释,以便在使用此技巧之前首先进行调试。
归档时间: |
|
查看次数: |
2155 次 |
最近记录: |