所以我看到堆栈初始化如下
pushl %ebp
movl %esp, %ebp
subl $constant, %esp
或只是
pushl %ebp
movl %esp, %ebp
我们的教授说我们不应该为%esp做subl指令,因为当我们在堆栈上推送东西时它会自动递减。那么为什么我们在使用subl指令时会看到这么多不同的汇编示例呢?何时使用它以及什么时候没有?
谢谢
答案 0 :(得分:4)
我认为你误解了导师试图说的话。导师试图说"不要写
subl $4, %esp /* reserve memory on the stack to save %ebx */
pushl %ebx /* save %ebx on the stack */
因为pushl
已经内置了subl $4, %esp
。"
换句话说,pushl %ebx
大致相当于
subl $4, %esp
movl %ebx, (%esp)
(不完全是因为旗帜,但你明白了。)因此,你不需要做subl $4, %esp
,因为那是pushl
的一部分。如果你自己做subl $4, %esp
,那么你将%esp
递减8而不是4。
另一方面,如果你想在堆栈上保留内存而不是推送寄存器,那么继续使用subl
。
答案 1 :(得分:2)
堆栈帧设置后面的sub
指令为堆栈上的空间保留所需的任何局部变量。
如果您没有基于堆叠的本地人,但只使用注册表,那么您就不需要它。
答案 2 :(得分:1)
push
和subl $K, %esp
都将递减%esp
,从而在堆栈上保留空间。您可以选择自己喜欢的内容 - push
可能更容易阅读 - 但您不应该同时阅读。
如果您打算在堆栈上存储SIMD值,那么确保与subl
保持对齐会更容易一些。