Why stack pointer %rsp is not (always) grown before using it?

199 views Asked by At

I wrote a small example program to play around with:

int f(int x){
  x = x + 1;
  return x;
}

int main(){
  int x = 10;
  x = f(x);
  return 0;
}

Compiled on x86-64:

gcc -o simple simple.c

And looked at disassembly for f():

Dump of assembler code for function f:
   0x00000000004004cd <+0>:     push   %rbp
   0x00000000004004ce <+1>:     mov    %rsp,%rbp
=> 0x00000000004004d1 <+4>:     mov    %edi,-0x4(%rbp)
   0x00000000004004d4 <+7>:     addl   $0x1,-0x4(%rbp)
   0x00000000004004d8 <+11>:    mov    -0x4(%rbp),%eax
   0x00000000004004db <+14>:    pop    %rbp
   0x00000000004004dc <+15>:    retq   

What throws me off a little bit is that it's writing to %rbp-0x4, with %rbp equal to %rsp at this point. What this means is we're writing 4 bytes beyond the top of the stack. I see why it's perfectly okay to do, since f() doesn't call anything, so stack will never grow unexpectedly here. But it still feels a bit strange. Is that some kind of optimization to save sub 0x4, %rsp and add 0x4, %rsp instructions?

Compiled with gcc (GCC) 4.8.5

0

There are 0 answers