【0】写在前面

过程(栈帧结构是干货);本文总结于csapp, 加上自己的理解;

【1】栈帧结构

每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。

过程调用:函数调用另一个词语表示叫作过程;

IA32 程序 用程序栈 来支持过程调用;

【2】转移控制

(此处非常重要:关系到对函数调用和返回理解是否到位)

解说:显然是地址80483dc的call调用sum函数, call指令的效果是将返回地址0x080483e1压入栈中,再跳转到sum函数的第一条指令(0x0804394),直到遇到ret指令为止,即是说,ret指令是一个函数的结束标志;
call == push ip ; jmp near ptr 标号;(压栈后跳转)
ret == pop ip;(出栈)

【3】寄存器使用惯例

惯例——我们必须保证当一个过程(调用者)调用另一个过程(被调用者)时,
被调用者不会覆盖某个调用者稍后会使用的寄存器的值。
  • 寄存器%eax, %edx 和 %ecx 被划分为调用者保存寄存器。(意思就是左边3个寄存器实现覆盖时,需要保存到调用者的栈帧结构中)
  • 寄存器%ebx, %esi 和 edi 被划分为被调用者保存寄存器。(意思就是左边3个寄存器实现覆盖时,需要保存到被调用者的栈帧结构中)

看个荔枝:

int P(int x)
{int y = x * x;int z = Q(y);return y + z;
}

过程P在调用Q之前计算y, 但它必须保证y的值在Q返回后是可用的。有两个方法可以实现:

  • (1)Q调用之前,将y的值保存到调用者P的栈帧结构中;当Q返回时,过程P从栈中取出y的值;
  • (2)将y保存在被调用者Q所保存的寄存器中,如%ebx等3个寄存器;如果Q或者其他的程序要使用这个寄存器的话,先把该寄存器的值压入栈帧中,并在返回前恢复该值;(因为每个函数或过程都有栈帧结构,谁要使用保存y的寄存器,谁就把y保存在其对应的栈帧中)

【4】过程实例

函数A调用函数B有三个过程:(其实上述的转移控制的解说已经说的很清楚了)

  • (1)建立部分,初始化栈帧;(把call指令的下一条指令的地址压入栈帧结构)
  • (2)主体部分,执行过程的实际计算;(执行被调用函数或者过程)
  • (3)结束部分,恢复栈的状态,以及过程返回;(将call指令的下一条指令的地址出栈到ip 或者叫做程序计数器pc)

我的观点 -干货:

(1)说说%ebp:

它其实是%esp的一个副本,作用在于记录每个执行函数或过程的栈帧结构的首地址(注意是每个函数或过程),如函数A调用函数B, 函数B的汇编代码的第一句就要把函数A的栈帧首地址压入栈,以便函数B结束标志ret指令执行前的一条指令,将其调用者——函数A的栈帧首地址弹回到%ebp;(参看上上图中的swap_add的汇编指令接近尾部部分)

为什么GCC分配从不使用的空间?

GCC 坚持一个X86编程指导方针,也就是一个函数使用的所有栈空间必须是16字节的整数倍;采用这个规则是为了保证访问数据的严格对齐。

再来看一个荔枝

执行时,%esp=0x800040, 而%ebp=0x800060, scanf返回后 的栈帧图结构, 如下:

干货-这里又是一个——很好的解释了C语言中的传值和传址的问题

为什么分配的栈帧空间中,还有没有被使用的?
这个问题,你不要问我了,自己多思考,答案就在附近,哈哈。


【5】递归过程

先看个荔枝(对于理解递归运算过程——至关重要)



干货-(这里, 你也可以看到, 对于参数n,它是存储在调用者的栈帧结构中的;从而解释了为什么取用参数的时候,都是%ebp+8;Bingo!)

过程(栈帧结构是干货)相关推荐

  1. java虚拟机栈帧_Java虚拟机,运行时栈帧结构

    业余生活要有意义,不要越轨.--华盛顿 引导语 "虚拟机"是一个相对于"物理机"的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器. ...

  2. 11.JDK8内存模型、本地方法栈、虚拟机栈、栈帧结构(局部变量表、操作数栈、方法出口、虚拟机栈与本地方法栈的关系、寄存器、方法区、堆(Heap)、jvm中的常量池、Metaspace(元空间))

    11.JDK8内存模型 11.1.本地方法栈(Native Method Stacks) 11.2.虚拟机栈(Java Virtual Machine Stacks) 11.3.栈帧结构 11.3.1 ...

  3. JVM007_运行时栈帧结构

    运行时栈帧结构 执行引擎是JVM的核心组件之一. 所有Java虚拟机的执行引擎输入输出都是一致的:输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果. JVM以方法作为作基本 ...

  4. Java虚拟机运行时栈帧结构--《深入理解Java虚拟机》学习笔记及个人理解(二)

    Java虚拟机运行时栈帧结构(周志明书上P237页) 栈帧是什么? 栈帧是一种数据结构,用于虚拟机进行方法的调用和执行. 栈帧是虚拟机栈的栈元素,也就是入栈和出栈的一个单元. 2018.1.2更新(在 ...

  5. java帧结构_Java虚拟机运行时栈帧结构--《深入理解Java虚拟机》学习笔记及个人理解(二)...

    Java虚拟机运行时栈帧结构(周志明书上P237页) 栈帧是什么? 栈帧是一种数据结构,用于虚拟机进行方法的调用和执行. 栈帧是虚拟机栈的栈元素,也就是入栈和出栈的一个单元. 2018.1.2更新(在 ...

  6. 函数调用过程中的栈帧结构及其变化

    前言:本文旨在从汇编代码的角度出发,分析函数调用过程中栈帧的变化. 栈帧的简单介绍: 当某个函数运行时,机器需要分配一定的内存去进行函数内的各种操作,这个过程中分配的那部分栈称为栈帧.下图描述了栈帧的 ...

  7. java 参数类型不确定_详细解析Java虚拟机的栈帧结构

    什么是栈帧? 正如大家所了解的,Java虚拟机的内存区域被划分为程序计数器.虚拟机栈.本地方法栈.堆和方法区.(什么?你还不知道,赶紧去看看<Java虚拟机内存结构及编码实战>)这次要介绍 ...

  8. arm gcc栈帧结构(1)

    2019独角兽企业重金招聘Python工程师标准>>> 摘要:先看个例子: void test2(int a,int b,int c) { int k=a,j=b,m=c; } GC ...

  9. 运行时栈帧结构是怎样的?

    写在前面 本文隶属于专栏<100个问题搞定Java虚拟机>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见100个问题搞定Java ...

最新文章

  1. 和方舟rust一样的手游_方舟生存进化手游2.0版本的泰克科技有多强?恐龙大军都顶不住...
  2. python 文件操作 open()与with open() as的区别(打开文件)
  3. [云炬创业学笔记]第二章决定成为创业者测试2
  4. php toupper,jquery如何进行字母大小写转换?
  5. 理解Joomla!模板
  6. 关于java线程同步的笔记_线程同步(JAVA笔记-线程基础篇)
  7. 打开Morrowind版本,Vector 36在Linux上的本机版本以及Hyper Light Drifter
  8. php实现抽象工厂模式(转)
  9. 极光IM JAVA后台对接
  10. 存储大师新作,三星存储四大新品面世!
  11. StringUtil.isEmpty()和StringUtil.isBlank()的区别
  12. Adober Pro DC 破
  13. 【虚拟光驱怎么安装Win7系统】
  14. 微信小程序-腾讯地图报错:鉴权失败,请传入正确的key
  15. android的sd卡分区,AndroidSD卡做磁盘分区图文教程
  16. 银耳椰椰——Alpha冲刺Day01
  17. java wtc_java通过wtc调用tuxedo服务超时
  18. 他励直流电动机的启动
  19. 使用flash id不拆盘查看SSD颗粒
  20. 大数据主要有什么用,有什么价值?

热门文章

  1. CERC17 Problem L - Lunar Landscape(差分,坐标系)
  2. P1232 [NOI2013] 树的计数
  3. 线性筛素数的实现与证明
  4. P2611-[ZJOI2012]小蓝的好友【Treap,扫描线】
  5. P5502-[JSOI2015]最大公约数【分治】
  6. AT4513-[AGC030D]InversionSum【dp】
  7. P1407-[国家集训队]稳定婚姻【tarjan,强连通分量】
  8. 2018/7/8-纪中某C组题【jzoj1619,jzoj1620,jzoj1621,jzoj1622】
  9. 小麦亩产一千八(jzoj 3461)
  10. 15、sql编程基本语法介绍