问题
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
回答1:
Assuming that the stack pointer is 16-byte aligned when func
is entered, then the combination of
pushq %rbp ; <- 8 bytes
movq %rsp, %rbp
subq $8, %rsp ; <- 8 bytes
will keep it 16-byte aligned for the subsequent call to foo()
.
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.
来源:https://stackoverflow.com/questions/22941372/gcc-4-7-2-in-debian-wheezy-doesnt-always-properly-align-stack-pointer-is-this