函数调用堆栈的过程

函数在进行调用时会产生开栈和清栈的操作,那么就来介绍一下函数调用堆栈的过程吧

首先,利用一个小例子来研究这个过程:

#include


int Fun(int a,int b)
{
	int tmp = 0;
	tmp = a + b;
	return tmp;
}


int main()
{
	int a = 10;
	int b = 20;
	int res = 0;
	res = Fun(a, b);
	std::cout << res << std::endl;
	return 0;
}

我们通过调试的反汇编功能可以看到主函数以及Fun函数执行时的反汇编代码:

main函数:

函数调用堆栈的过程_第1张图片

 Fun函数:

函数调用堆栈的过程_第2张图片

在看这个之前,我们得先了解一下基本符号的意义

1)eax ebx ecx edx:均为寄存器,用来存储数据;

2)ebp esp(ebp为栈底指针,esp为栈顶指针);

3)mov eax,10 =>eax = 10;给eax寄存器赋值为10;

4)lea eax,[a] 将a的地址赋值给eax寄存器;

5)push 入栈

6)pop 出栈

7)sub add 加减运算

8)mov eax,dword ptr[a] 将a的值移动到eax中

接下来详细的解释一下整个过程:
函数调用堆栈的过程_第3张图片

 总结一下:

  1. 首先开辟调用方栈帧,将栈帧初始化;
  2. 压入实参,然后自右向左初始化形参;
  3. 将call指令的下一行指令的地址压入栈;
  4. 将调用方栈底地址压入栈中;
  5. 跳转到被调用方的栈帧中,并开辟内存;
  6. 函数返回值返回
    1)返回值 < 4字节  利用eax寄存器带回;
    2)4字节 < 返回值 < 8字节  利用eax,edx寄存器带回;
    3)返回值 > 8字节  利用临时量带回;
  7. 利用栈中存储的调用方栈底的指针回退到调用方栈中;
  8. 调用约定
    1)_cdecl   C标准调用约定
    2)_stdcall  windows标准调用约定
    3)_fastcall  快速调用约定
    4)_thiscall 类成员方法的调用约定

你可能感兴趣的:(C++)