zoukankan      html  css  js  c++  java
  • gdb调试汇编堆栈分析

    代码(src/05/gdb.c)

    int g(int x)
    {
      return x + 4;
    }
    
    int f(int x)
    {
      return g(x);
    }
    
    int main(void)
    {
      return f(8) + 4;
    }
    

    gcc编译

    使用gcc -g src/05/gdb.c -o gdb -m32命令在64位的机器上产生32位汇编代码

    gdb调试可执行文件

    • 使用gdb gdbdemo指令打开gdb调试器

    • 使用break main指令在main函数处设置断点,使用r指令运行代码,可以看到运行时在main函数位置停了下来

    • 使用disassemble指令获取汇编代码

    • 用i r指令查看各寄存器的值

    • 此时主函数的栈基址为0xffffcf68,用x 0xffffcf68指令查看内存地址中的值,目前%esp所指堆栈内容为0,%ebp所指内容也为0

    • 使用display /i $pc指令进行设置,在每次执行下一条汇编语句时,都会显示出当前执行的语句。

    • 依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:
      1、使用si指令单步跟踪一条机器指令
      2、使用i r指令查看各寄存器的值
      3、使用x/na %esp对应的值指令查看堆栈变化

    • %esp、%ebp和堆栈内容变化

    • call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:

    • 将上一个函数的基址入栈,从当前%esp开始作为新基址:

    • 为传参做准备:

    • 实参入栈:

    • call指令将下一条指令的地址入栈:

    • 分配栈空间

    • pushl 0x8(%ebp)将%esp中的8存入栈中

    • 将 %eax 与立即数4相加

    • pop %ebp在g结束前弹栈

    • ret返回g中call的调用位置,结束g函数

    • 将 %esp 与立即数相加

    • leave返回准备栈

    • ret返回f中call的调用位置,结束f函数

    • 进入main函数,将 %esp 与立即数相加

    • 将 %eax 与立即数4相加

    • leave返回准备栈

    • ret结束main函数

    • 分析

    参考

    -GDB调试汇编堆栈过程分析

  • 相关阅读:
    使用线程池对应用程序产生线程个数与占用CPU时间的影响
    枚举类型解析
    性能监视器的简单使用
    WCF 承载服务
    ManulResetEvent与AutoResetEvent
    获取当前目录的上级目录
    WCF 异步调用
    适配器设计模式
    控制控制台自身的最大化最小化
    代码自动生成技术相关介绍
  • 原文地址:https://www.cnblogs.com/20145327gc/p/6119463.html
Copyright © 2011-2022 走看看