函数栈帧非战争

如果能理解函数栈帧的创建与销毁 可以大大提高我们理解c语言其他知识点的能力

接下来我用vs2019的环境给大家简单讲解一下函数栈帧的创建与销毁

因为会用到汇编 所以先给大家介绍几个汇编指令和要用到的寄存器

大家要注意的是栈区使用规则是先使用高地址 在使用低地址

在本文章中 下面是高地址 上面是低地址

 用一段及其简单的调用函数来调试这个过程 

要注意的是有其他函数来调用main函数

 当我们运行程序我们转到反汇编  

上来就是三个压栈 注意压栈的同时esp也会变动

 

 下面看到的指令就是数据的创建过程

 调用add之前 这个过程其实就是传参

 

 把ebp-14h的值给eax把eax压入栈顶

把ebp-8的值给ecx把ecx压入栈顶

ebp-14h是什么?ebp-8是什么?恰好就是我们创建的变量a和b

注意的是 我们是先压的b后压的a 这个和我们的函数传参有关 是从右向左依次压栈

 

 然后是call指令

注意call指令存的是返回main函数时 继续执行的语句的地址

 call执行时会压入返回地址  并进入目标函数

 此时我们已经进入了MyAdd函数

 在栈顶压入一个ebp 注意此时ebp里的值就是main函数的ebp

然后在把esp的值移动给ebp 并且让esp - 0cch

 继续压栈

 

 

 这段指令我不多做解释就是一个初始化的过程把这段内存的值全部变成ccccccc

这就是有时我们打印出烫烫烫烫烫烫烫烫的原因

 看我们是怎么使用传参变量的

ebp+8的值放进eax里

在用eax加上ebp+0ch

 注意看是不是我们进入add函数之前压进去的 同过ebp加减来寻找这个地址

但是注意的事把这个值存在了eax寄存器里

在看mov的指令 把eax的值给ebp - 8

 当然上面的代码还是不够详细

如果是先创建一个int z=0;

z=x+y; 就会比这个详细 但道理是一样的

此时我们已经完成加法 但是还没有返回

 我们开始弹栈

 

 add,0cch  记得我们之前创建时是sub,0cch

也就是把esp的位置还回去了

mov  把ebp的值放进esp里 

然后把ebp pop掉

ret  恢复返回地址 注意的是现在存的 是不是就是之前main函数的ebp

恢复之后ebp 就回到了main最开始的ebp那个位置

 ret还要压出一个值

 

add esp+8

也就把esi和ebx  pop掉了

 然后才开始接受返回的值

大家看到这还记得 我们之前把加完的值存入了eax里

mov指令 把eax的值移动给ebp-20h

 这就是一个函数栈帧的创建和销毁了

接下来我们总结一下 

1.调用函数,需要先形成临时拷贝,形成过程是从右向左的

2.临时空间的开辟,是在对应的栈帧里内部开辟的

3.函数调用 完毕,函数的栈帧会被销毁

4.临时变量具有临时性的本质是因为函数栈帧存在临时性

5.函数调用时有成本的,体现在时间和空间上,本质是因为调用函数时创建栈帧和销毁栈帧有成本

6函数调用,因拷贝形成的临时变量,位置是挨着放的 有规律的

大家觉得有收获的话点个赞吧

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值