我写了一个小示例程序来玩:
int f(int x){
x = x + 1;
return x;
}
int main(){
int x = 10;
x = f(x);
return 0;
}
在 x86-64 上编译:
gcc -o simple simple.c
并查看了反汇编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
让我有点失望的是它正在写入%rbp-0x4
,此时%rbp
等于%rsp
。这意味着我们在堆栈顶部之外写入 4 个字节。我明白为什么这样做完全没问题,因为f()
不调用任何东西,所以堆栈永远不会在这里意外增长。但是感觉还是有点奇怪。sub 0x4, %rsp
这是保存和add 0x4, %rsp
指令的某种优化吗?
编译gcc (GCC) 4.8.5