为了解函数调用的底层实现机制,通过visual studio 2010及一段代码来剖析,代码如下:
1. #include <stdio.h>
2.
3. int GetSum(int a,int b)
4. {
5. return a+b;
6. }
7.
8. int main()
9. {
10. int a = 10;
11. int b = 20;
12. int sum = GetSum(a,b);
13. return 0;
14. }
如下图是mian函数的初始化反汇编代码及图像解释:
接下来是main函数的局部变量开辟内存直到函数调用:
当上述过程完成后跳转到被调用方函数:
在被调用函数的反汇编代码最后一步可以看到,a+b的值在eax寄存器里面。接下来是被调用方清栈:
函数调用完成,跳转回主函数:
总结:
- 形参由调用方在栈上开辟,入栈顺序为从右至左
- 被调用方返回值的带出(非类类型):
0-4字节:eax寄存器
4-8字节:edx、eax寄存器
8字节以上:临时量带出来
3.被调用方保存着调用方的栈底地址,因此调用完成后可以回到调用前
4.形参压栈完成后,保存着下一行指令的地址,因此可以沿着调用点继续往下执行