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