【问题标题】:When should I use the RSP register to add space to the stack?何时应该使用 RSP 寄存器向堆栈添加空间?
【发布时间】:2019-03-29 17:17:30
【问题描述】:

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

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

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

我知道使用 sub rsp 增加堆栈应该在函数调用之前使用,而 add rsp 应该在函数调用之后使用。

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

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

【问题讨论】:

  • push rbx 在 x86-64 上保存/恢复 RBX 完全没问题。如果您为超过 8 个字节的本地变量保留空间,并且还没有要存储的值,那么您通常会使用 sub 而不是多个虚拟推送。
  • @PeterCordes 这样就更清楚了,感谢您的回复!我仍然无法准确掌握何时需要将值压入堆栈,但我会解决的,哈哈

标签: stack x86-64 nasm intel cpu-registers


【解决方案1】:

一些栈原理:

根据两个主要的调用约定,包括在 MacOS 上使用的 x86-64 System V ABI,在函数调用之前堆栈需要16 字节对齐。如果不是,您在调用外部函数时会冒着分段错误的风险。 (例如,因为它们被允许假设对齐并使用 movaps 进行 16 字节的堆栈内存复制。)

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

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

例如,您可以这样做:

sub rsp,16

push rax
push rax

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


对于仅将堆栈指针移动 8 位,虚拟 push 或 pop 可以与add/sub 一样有效或更有效。除此之外,通常不会。

【讨论】:

  • 这对我帮助很大!我还有很多东西要学,但理解这一点对我能够继续前进很重要,非常感谢!!
猜你喜欢
  • 1970-01-01
  • 2021-06-10
  • 2015-03-11
  • 2023-04-02
  • 1970-01-01
  • 2012-06-12
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多