Debian中的gcc 4.7.2 wheezy并不总是正确对齐堆栈指针。这是一个错误吗?

时间:2014-04-08 15:24:39

标签: c gcc calling-convention

随便在读取示例C程序的汇编列表时,我注意到在调用函数foo之前堆栈指针不是16位对齐:

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

subq $8, %rsp指令在调用foo之前使RSP不对齐(它应该是“subq $ 16,%rsp”)。
在System V ABI中,参数。 3.2.2,我读到:“当控制转移到功能入口点时,值(%rsp - 8)总是16的倍数。”
有人可以帮我理解为什么gcc没有放subq $16, %rsp
提前谢谢。

编辑: 我忘了提及我的操作系统和编译器版本:
Debian wheezy,gcc 4.7.2

1 个答案:

答案 0 :(得分:1)

假设在输入func时堆栈指针是16字节对齐的,那么

的组合
pushq %rbp              ; <- 8 bytes
movq  %rsp, %rbp
subq  $8, %rsp          ; <- 8 bytes

将保持16字节对齐,以便随后调用foo()

似乎因为编译器知道foo()的实现并且它是一个noop,所以它不会对堆栈对齐感到困扰。如果foo()仅被视为编译func()的翻译单元中的声明或原型,您将看到预期的堆栈对齐。