zoukankan      html  css  js  c++  java
  • 过程(栈帧结构是干货)

    【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!)

  • 相关阅读:
    echarts饼状图位置设置
    去除echarts饼状图的引导线
    VS2008里的代码如何格式化
    使用ADO如何获得SQLSERVER 2K的数据库名的列表
    CStdioFile.WriteString无法向文件写入中文
    使用ODBC 数据库 ,运行程序时 出现 “遇到不适当的参数”
    CListCtrl消息及解释
    VC的CListCtrl控件
    找不到Microsoft Access Driver(*.mdb)ODBC驱动程序的安装例程。请重新安装驱动
    WebBrowser 控件-说明
  • 原文地址:https://www.cnblogs.com/pacoson/p/4893173.html
Copyright © 2011-2022 走看看