Question

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

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top