一、内存结构
内存大致可以分为四个部分:代码段,静态存储区,堆,栈。
具体划分如下图所示:

栈:在执行函数时,函数内部局部变量的存储单元都可以在栈上创建,函数执行结束后会自动释放内存。栈内存的分配运算内置于处理器的指令中。效率高,但分配的内存容量有限,程序发生错误时,很有可能出现栈溢出。
堆:又称为动态内存分配区,程序在执行的时候用malloc或new申请指定大小的内存,程序员自己负责在任何时候用free或delete释放内存。若在申请后未释放,在程序结束时有可能会有OS自动回收,或者造成内存泄露,因此,使用时一定要注意。
静态存储区:包括程序中明确被初始化的全局变量、静态变量、常量以及未被初始化的数据。内存在程序编译时已经分配好,这块内存在整个运行期间一直存在。
代码区:存放程序代码,代码区是可以共享的(其他的执行程序可以调用它),整个内存中只有一份。

栈和堆的区别
1.管理方式不同
栈由编译器自动管理,堆由程序员控制。
2.空间大小不同
栈是向低地址扩展的结构,是连续的内存区域,因此栈顶和栈底是规定好的,容量有限,若用户使用过多的栈空间,会产生溢出。堆是向高地址扩展,不是连续的内存区域,堆获得的空间较大,分配时也比较灵活。
3.是否产生碎片
对于堆来说,频繁的malloc/free,new/delete会是空间不连续,造成大量碎片,使得程序效率降低。而栈不存在这样的问题。
4.增长方向不同
堆和栈相对生长
5.分配方式
堆由程序员通过使用malloc、free、new、delete来进行管理。栈由编译器申请释放,栈的动态内存分配通过alloca函数完成。
6.分配效率不同
栈是机器系统提供的数据结构,计算机在底层对栈提供支持。堆是C库函数提供的,堆的效率比栈低得多。

二、函数的调用过程(栈帧)
每一次的函数调用都是一个过程,我们将这个过程称为函数的调用过程。在这个过程中,会开辟栈空间用来保存本次函数调用过程中临时变量以及现场保护等工作,这块栈空间我们称之为函数栈帧。栈帧的维护需要两个寄存器也叫帧指针,即ebp和esp,esp中存放栈顶地址,ebp存放栈底地址。esp和ebp一次只能存放一个地址。
以下是函数调用的详细过程:

假设函数a调用了函数b,函数b调用了函数c,函数b有三个参数,从左至右依次为参数1,参数2,参数3。
1.函数a在调用函数b的时候,首先将函数b的参数以相反的顺序依次压入栈中,即,从最后一个参数开始压栈。
2.函数a使用call指令调用函数b,并将call指令下的一条指令的地址当做返回地址压入栈中。(汇编call命令的两个功能:1.保存当前指令的下一个指令的地址。2.pc指针跳转到调用函数的入口地址。)
3.在函数b的栈帧中,首先保存函数a的栈底地址,再将函数a的栈顶地址当做函数b的栈底地址,即图中所示的push ebp和mov ebp,esp这两条指令。
4.然后,从ebp的位置开始存放函数b的局部变量,将这些变量的地址依次存放在栈中,先定义的先入栈,后定义的后入栈。
注意:在不同的编译器上函数的调用过程可能会有所不同,但大致思想相同。

汇编的堆栈操作指令
1:栈是自顶向下生长
2:栈是先入后出的数据结构
3:push会使esp-4
4:pop会使esp+4
临时存放数据
传递参数
保存和恢复寄存器 PUSHF/POPF

c函数调用过程的更多相关文章

  1. 从一个新手容易混淆的例子简单分析C语言中函数调用过程

    某天,王尼玛写了段C程序: #include <stdio.h> void input() { int i; ]; ; i < ; i++) { array[i] = i; } } ...

  2. c函数调用过程原理及函数栈帧分析

    转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比 ...

  3. 函数调用过程&生成器解释

    摘自马哥解答,感谢. 函数调用过程: 假设程序是单进程,单执行流,在某一时刻,能运行的程序流只能有一个.但函数调用会打开新的执行上下文,因此,为了确保main函数可以恢复现场,在main函数调用其它函 ...

  4. Linux驱动调试-根据oops的栈信息,确定函数调用过程

    上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的,那如何通过栈信息来查看出错函数的整个调用 ...

  5. C语言的函数调用过程

    从汇编的角度解析函数调用过程 看看下面这个简单函数的调用过程: int Add(int x,int y) { ; sum = x + y; return sum; } int main () { ; ...

  6. 37.Linux驱动调试-根据oops的栈信息,确定函数调用过程

    上章链接入口: http://www.cnblogs.com/lifexy/p/8006748.html 在上章里,我们分析了oops的PC值在哪个函数出错的 本章便通过栈信息来分析函数调用过程 1. ...

  7. 深入理解C语言的函数调用过程 【转】

    转自:http://blog.chinaunix.net/uid-25909619-id-4240084.html 原文地址:深入理解C语言的函数调用过程 作者:wjlkoorey258     本文 ...

  8. C语言的函数调用过程(栈帧的创建与销毁)

    从汇编的角度解析函数调用过程 看看下面这个简单函数的调用过程: int Add(int x,int y) { ; sum = x + y; return sum; } int main () { ; ...

  9. C++函数调用过程深入分析<转>

    转自http://blog.csdn.net/dongtingzhizi/article/details/6680050 C++函数调用过程深入分析 作者:靠谱哥 微博:洞庭之子-Bing 0. 引言 ...

  10. 用systemtap跟踪打印动态链接库的所有c++函数调用过程

    http://gmd20.blog.163.com/blog/static/168439232015475525227/             用systemtap跟踪打印动态链接库的所有c++函数 ...

随机推荐

  1. sqlserver update join

    update a set a.UserAgent = b.UserAgent from InfoVisitDetails a inner join InfoVisitDetails b on a.IP ...

  2. 可以编译驱动,编译ch34x驱动后,不能编译驱动了

    编译驱动时,得先把内核编译好: 已经成功编译了01驱动: 后来编译ch34x驱动,发现编译不成功: 然后再编译01驱动也不成功了: 再次编译内核,再编译01就能编译了: 能力有限,不知道为什么,记录下 ...

  3. observObservableCollection改变model属性UI不更新

    使模型类实现INotifyPropertyChanged即可 public class ResDepartmentData : INotifyPropertyChanged { //需要更新UI的属性 ...

  4. cisco ios 密码恢复

    如果没有break键,使用仿真软件模仿一个break 密码恢复请执行以下步骤 1. 关闭或断开路由器电源 2.开启路由器.在通电后的前30秒内按下break键(或通过仿真程序发送一个间断序列),来中断 ...

  5. android 实现检测版本,下载apk更新(附源码)

    其实这不是什么难事了,都有热更新的技术了,只是记录一下,大神勿嘲笑. 先说下思路,首先要有更新的接口,只要进入app,就监测一下接口,是否更新,更新的话,检测本地版本是否低于接口返回的版本,低的话,就 ...

  6. 下载nodejs和vue

    下载nodejs https://nodejs.org/en 下载或更新npm npm install cnpm -g npm install -g vue 全局安装 创建一个基于 "web ...

  7. js开发环境如何解决跨域问题

    问题 npm start之后,自己会启动一个端口,比如3000,调用后端服务(比如localhsot:3006/service/list)就会出现跨域,那怎么弄呢? 方式一: webpack设置pro ...

  8. sping入门介绍-bean标签的属性

    bean标签的属性 1 .基础属性 <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" ...

  9. 如何用adb连接android手机

    如何用adb连接android手机 以下为手机"root"情况下操作....手机没root请拉到笔记最后,有解决方法 利用adb来连接手机, 有两种方式: wifi usb 通过w ...

  10. 新手搭建Git与项目整合

    新手搭建Git,将代码托管到码云 如果你还没有使用过Git,首先先去https://gitee.com/注册一个自己的账户,然后在https://git-scm.com/下载一个客户端(提交代码到码云 ...