一个函数到底是怎么调用的,返回值是如何返回的,这里面学问真的很多,让我们来小小的分析一下。。。。
我们看一个很简单的C代码,通过gdb调试来分析函数调用过程。
平台和工具:ubuntu12.04+gcc 4.6.3+GNU gdb 7.4-2012.04
cs.c:
int add(int a,int b)
{
return a+b;
}
int main()
{
int a=1;
int b=2;
int c=add(a,b);
}
编译: gcc -g cs.c
调试:gdb a.out
我们看一下:main函数的汇编代码:
(gdb) disas main
Dump of assembler code for function main:
01 0x080483c1 <+0>: push %ebp
02 0x080483c2 <+1>: mov %esp,%ebp
03 0x080483c4 <+3>: sub $0x18,%esp
04 0x080483c7 <+6>: movl $0x1,-0xc(%ebp)
05 0x080483ce <+13>: movl $0x2,-0x8(%ebp)
06 0x080483d5 <+20>: mov -0x8(%ebp),%eax
07 0x080483d8 <+23>: mov %eax,0x4(%esp)
08 0x080483dc <+27>: mov -0xc(%ebp),%eax
09 0x080483df <+30>: mov %eax,(%esp)
10 0x080483e2 <+33>: call 0x80483b4 <add>
11 0x080483e7 <+38>: mov %eax,-0x4(%ebp)
12 0x080483ea <+41>: leave
13 0x080483eb <+42>: ret
End of assembler dump.
为了方便我在每行前面加了序号(本来是没有的)
堆栈情况如下:
图1
下面的数字代表main函数反编译的行号
1.帧指针ebp入