函数调用过程

函数调用过程

寄存器:cpu 中的变量

esp:栈顶寄存器
ebp:栈顶寄存器

struct Node
{
	int _1;
	int _2;
	int _3;
};

struct Node _cdecl fun(int a,int b)
{
	int c=30;
	//c=a+b;
	struct Node c={10,20};
	return c;
}

int main()
{
	int a=10;
	int b=20;
	int c;
	//struct Node a={10,20,30};
	//struct Node b={40,50,60};
	struct Node c=fun(a,b);
	return 0;
}
  1. 参数入栈

    在这里插入图片描述
    4字节参数入栈;
    顺序:从右向左;
    方式:使用寄存器push带入;

    操作数据是通过CPU进行操作,
    
    入栈顺序:从b地址中取dword 4字节放到eax寄存器中;
    
    move 取值;    push入栈;
    

在这里插入图片描述

	8字节参数入栈;
	顺序:从右向左;
	方式: 使用寄存器push 带入

在这里插入图片描述

		12字节参数入栈
		sub 减   //esp=esp-0c;
		顺序:从右向左;
		方式:先在栈顶开辟足够该参数的空间,之后将数据赋值进去;

C++中只要是自定义类型,无论多大字节,都采用先开辟空间,之后赋值的方式。

  1. 函数栈帧开辟

在这里插入图片描述

	将调用方函数下一行指令地址入栈;
	将调用方函数的栈底寄存器入栈;
	让ebp=esp;
	让esp=esp-***;
	将其他使用的寄存器入栈;
	将新开辟的栈帧空间中全部写为cccc cccc;
  1. 返回值返回

在这里插入图片描述

4字节返回值
方式:将返回值放入寄存器带回;

在这里插入图片描述

8字节返回值
方式:将返回值放在两个寄存器,带回

在这里插入图片描述

12字节返回值
方式:首先在函数参数入栈之后,入栈一个调用方栈帧上的地址(靠近栈顶位置);
在函数值返回的时候,将返回数据写入到之前入栈的地方地址上;
返回之后,将从该地址上将数据取出;

C++中,自定义类型都按照入栈调用方地址的方式。

  1. 函数栈退出

在这里插入图片描述

进行当前函数栈帧的校验;
将线程保护的寄存器出栈;
让esp=ebp;
ebp=pop;
将下一行指令的地址还原;
清楚参数。

当前演示的函数调用过程依赖于c语言默认的调用约定 _cdecl;

还有其他调用约定: _stdcall
_fastcall

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值