zoukankan      html  css  js  c++  java
  • linux c 程序函数调用栈帧分析

    唐建 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

    一、本文目的

          将自己跟踪linux c程序函数调用栈帧的情况mark 一下,以便后续可以查阅。网友们发现有误的,请直接指正。同时此文为我向孟宁老师学习内核的课间作业

    二、函数原型

          为了更加直观的描述栈帧,所以写了一个非常简单的函数调用例子,这样便于理解栈帧的情况。

    三个函数连续调用,同时直接进行值传递和返回,并进行加法运算。

    三、下面将函数汇编出来的汇编代码也贴出来以便。

     从上往下分别是main() 、f()、g()三个函数。

    从上面的汇编代码我们可以简单总结一下:

    1、函数开始都是进行本函数的栈准备。

         push %ebp——保存上一个函数的栈现场

         push %esp,%ebp——开启当前函数的栈

    2、函数调用前,会先将参数入栈,然后调用call

    3、函数调用 call 实际上相当于 push %eip 和 goto 。保存当前函数的执行点,跳转到被调函数。

    4、函数结束,都是回复上一个函数的栈

         leave  =   mov %ebp,%esp   和 pop %ebp,这就是恢复上一个函数的栈

         ret = pop %eip ——恢复上一个函数的执行点,就是该执行哪条指令了。

    四、下面我们看一下通过汇编调试得到的栈帧

    1、调用

    Call 函数时会将跳转的下一条指令压栈:

    于是我们贴出来调用f函数时的栈帧

     

    上述红圈,栈底是到栈顶分别是入参(11)、下一条指令(0x8048406=134513670)、

     f()调用g()函数一样,我们下面贴出g()函数被调用后整体的栈帧。

    2、返回

    ret指令就是讲下一条指令出栈给eip,下图贴出的是f函数ret 返回时的情况

    Ret 完成后就回到了f函数的栈区了。同时大家可以下图看到,回到f函数后,会马上将之前的调用g函数的入栈的调用参数出栈——“add $0x4,%esp

    Leave 相当于

    mov ebp ,esp

    pop ebp 

    大家看下图,就是f函数返回时,栈帧的变换,栈变回了main函数的栈顶和栈底

    函数的返回值是通过eax寄存器传递的

  • 相关阅读:
    linux 解压命令
    在xampp集成环境下使用 thinkphp 连接oracle
    输入框实现新闻列表分页显示(一)
    MyEclipse获取注册码
    Oracle数据库创建表空间
    SQL Server之存储过程
    连接Oracle数据库帮助类
    Oracle数据库的导入和导出
    创建dml触发器
    java连接数据库步骤
  • 原文地址:https://www.cnblogs.com/tjyuanxi/p/8469913.html
Copyright © 2011-2022 走看看