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