何时应使用 RSP 寄存器向堆栈添加空间?



我有几个组装项目要实现,我对何时在堆栈上添加空间以及应该添加多少感到困惑。

我在 unix 系统 (macos) 英特尔x86_64上使用 NASM 版本 2.13.03。

我一直在阅读很多文档并做了很多研究,但没有一个以足够详细的方式解释我问题的答案。 我理解红色区域,并且叶函数不需要使用增加的堆栈。

我知道应该在函数调用之前使用通过使用 sub rsp 来增加堆栈,并且在函数调用之后应该使用添加 rsp。

我知道在 32 位架构上,您使用推送和弹出来增加堆栈,但在这个 64 位架构上,需要使用 sub rsp 并添加 rsp 以及 mov 指令来添加堆栈上的寄存器。

如果有人对使用此架构的堆栈有任何提示或解释,并解释何时增加堆栈以及应该提供多少,非常感谢!

一些 x86-64 堆栈原则:

根据两种主要的调用约定,堆栈需要在函数调用之前对齐16 字节,包括 MacOS 上使用的 x86-64 System V ABI。如果不是,则在调用外部函数时将面临分段错误的风险。 (例如,因为它们被允许假定对齐并将movaps用于堆栈内存之间的 16 字节副本。

有趣的事实 - 在MacOS上,当堆栈未对齐16字节时,系统调用确实可以正常工作。

对于push raxrax 值被推到堆栈顶部。
对于sub rsp,8,堆栈的顶部保持不变(因此内存中存在的任何内容都将保留在那里)。 对于两条指令,对 rsp 值的更改完全相同。

例如,您可以执行以下任一操作:

sub rsp,16

push rax
push rax

堆栈指针rsp指向完全相同的位置。


对于仅移动堆栈指针 8 个,虚拟推送或弹出可以与add/sub一样高效或更高效。 除此之外,通常不会。

最新更新