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

    分析过程

    1 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器:

    2 使用gdb调试代码。

    3 使用break main指令在main函数处设置断点,然后调试,直到mian函数处。

    4 使用diassemble指令获取汇编代码

    5 依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:

    (1)使用si指令单步跟踪一条机器指令

    (2)使用i r指令查看各寄存器的值

    (3)使用x/na %esp对应的值指令查看堆栈变化

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

    7 将上一个函数的基址入栈,从当前%esp开始作为新基址,以及为传参做准备

    8 实参的计算在%eax中进行:

    9 f函数的汇编代码:

    10 实参入栈:

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

    13 计算short+int:

    14 pop %ebp指令将栈顶弹到%ebp中,同时%esp增加4字节:

    15 ret指令将栈顶弹给%eip:

    汇编代码及分析:

    g:
    pushl %ebp // 将%ebp入栈
    movl %esp, %ebp // 将%ebp设置为目前这个程序的帧指针
    movl 8(%ebp), %eax //把保存在%ebp+8处的值x传送给%eax
    addl $3, %eax //执行语句x+3,将结果返回给%eax
    popl %ebp //弹出%ebp的值
    ret

    f:
    pushl %ebp //保存原来的%ebp(返回f的地址)
    movl %esp, %ebp //将%ebp设置为目前这个程序的帧指针,值为原%esp的值减去4
    subl $4, %esp //%esp向下移动4个单位,在栈上分配四个字节
    movl 8(%ebp), %eax //将%ebp+8位置的值保存给%eax
    movl %eax, (%esp) //将x的值赋值给x所指向的位置;
    call g //调用g函数,将返回地址压入栈中,然后调到函数g的第一条指令
    leave //为返回准备栈
    ret

    main: //主函数
    pushl %ebp //保存原来的%ebp(返回main的地址)
    movl %esp, %ebp //将%ebp设置为目前这个程序的帧指针,值为原%esp的值减去4
    subl $4, %esp //%esp向下移动4个单位,在栈上分配四个字节
    movl $8, (%esp) //把8赋值给%esp所指的位置
    call f //调用f函数,将返回地址压入栈中,然后调到函数f的第一条指令
    addl $1, %eax //执行表达式return f(8)+1,将%eax中的值加一再返回
    leave
    ret

  • 相关阅读:
    驱动下的异常处理
    头文件 .h 与源文件 .ccp 的区别
    驱动程序进阶篇
    驱动中链表的使用
    内存操作相关内核 API 的使用
    链表的概念、建立、删除与插入
    编写简单的 NT 式驱动程序的加载与卸载工具
    驱动程序入门篇
    c++ 指针的简单用法
    CTL_CODE 宏 详解
  • 原文地址:https://www.cnblogs.com/HZW20145322/p/6132418.html
Copyright © 2011-2022 走看看