问题描述
简单地说,在读取C程序的汇编列表时,我注意到在调用函数foo之前,堆栈指针不是16位对齐的: void foo(){}
int func(int p){foo();返回p; }
int main(){return func(1); }
func:
pushq%rbp
movq%rsp,%rbp
subq $ 8,%rsp;见这里
movl%edi,-4(%rbp)
movl $ 0,%eax
call foo
movl -4(%rbp),%eax
leave
ret
子$ 8,%rsp
指令在调用foo之前使RSP不对齐(它应该是subq $ 16,%rsp)。
在System V ABI中,par。 3.2.2,我读到:当控制转移到函数入口点时,值(%rsp - 8)总是16的倍数。
有人可以帮助我理解为什么gcc doesn' t把 subq $ 16,%rsp
?
先谢谢了。
编辑:
我忘了提及我的操作系统和编译器版本:
Debian wheezy,gcc 4.7.2
似乎编译器知道 foo()
而且这是一个noop,它不会打扰堆栈对齐。如果 foo()
在编译 func()
的翻译单元中被看作只是一个声明或原型,你会看到你预期的栈对齐方式。
Casually, when reading the assembler listing of a sample C program, I noted that the stack pointer is not 16 bit aligned before calling function foo:
void foo() { }
int func(int p) { foo(); return p; }
int main() { return func(1); }
func:
pushq %rbp
movq %rsp, %rbp
subq $8, %rsp ; See here
movl %edi, -4(%rbp)
movl $0, %eax
call foo
movl -4(%rbp), %eax
leave
ret
The subq $8, %rsp
instruction makes RSP not aligned before calling foo (it should be "subq $16, %rsp").
In System V ABI, par. 3.2.2, I read: "the value (%rsp − 8) is always a multiple of 16 when control is transferred to the function entry point".
Someone can help me to understand why gcc doesn't put subq $16, %rsp
?
Thank you in advance.
Edit:I forgot to mention my OS and compiler version:
Debian wheezy, gcc 4.7.2
It seems that since the compiler knows about the implementation of foo()
and that it's a noop, it's not bothering with the stack alignment. If foo()
is seen as only a declaration or prototype in the translation unit where func()
is compiled you'll see your expected stack alignment.
这篇关于在Debian中,gcc 4.7.2并不总是正确地对齐堆栈指针。这是一个错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!