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

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

测试代码

    #include<stdio.h>
    short addend1 = 1;
    static int addend2 = 2;
    const static long addend3 = 3;
    static int g(int x)
    
    return x + addend1;
    }  
    static const int f(int x)
    {
    return g(x + addend2);
    }
    int main(void)
    {
    return f(8) + addend3;
    }

分析过程

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

  • 进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值:
    886543-20161210205923694-373233152.png
    886543-20161210210048835-187638412.png

  • 可见此时主函数的栈基址为 0xbffff2d4,用x(examine)指令查看内存地址中的值,但目前%esp所指堆栈内容为0,%ebp所指内容也为0
    886543-20161210210139476-424756808.png

  • 首先,结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。下面展示每一步时%esp%ebp和堆栈内容的变化:
    886543-20161210210203507-124953531.png
    886543-20161210210226757-2079437749.png
    886543-20161210210239632-1617909507.png
  • call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
    886543-20161210210340944-559109263.png
    886543-20161210210359866-1371095593.png
    886543-20161210210412538-138012487.png
  • 将上一个函数的基址入栈,从当前%esp开始作为新基址:
    886543-20161210210458179-1866822095.png
    886543-20161210210519944-1869373135.png
    886543-20161210210534726-1654274942.png
  • 先为传参做准备:
    886543-20161210210616647-960249781.png
    886543-20161210210630351-1674103180.png
    886543-20161210210641741-1001189424.png
  • 实参的计算在%eax中进行:
    886543-20161210210707351-487644752.png
  • f函数的汇编代码:
    886543-20161210210913960-527306230.png
  • 实参入栈:
    886543-20161210210956147-1807420546.png
    886543-20161210211008882-530063650.png
    886543-20161210211019585-2084780025.png
    886543-20161210211121757-1202181185.png
    886543-20161210211143960-541752850.png
    886543-20161210211156351-126024590.png
    886543-20161210211432976-1837375881.png
    886543-20161210211442507-40931035.png
    886543-20161210211453241-566073867.png
  • call指令将下一条指令的地址入栈:
    886543-20161210211538944-2146557160.png
    886543-20161210211602022-444930742.png
    886543-20161210211612429-461244080.png
    886543-20161210211621663-1967125255.png
    886543-20161210211634726-742598722.png
    886543-20161210211649069-2105772017.png
  • 计算short+int:
    886543-20161210211729116-853305912.png
    886543-20161210211739757-1702999407.png
    886543-20161210211748897-1367539017.png
    886543-20161210211800101-264163544.png
    886543-20161210211812194-1970371880.png
    886543-20161210211825288-1253155156.png
    886543-20161210211834601-115991728.png
    886543-20161210211844132-2127203652.png
    886543-20161210211853866-1687678903.png
  • pop %ebp指令将栈顶弹到%ebp中,同时%esp增加4字节:
    886543-20161210211943429-1274442561.png
    886543-20161210211950835-1706131651.png
    886543-20161210212002569-398056884.png
    886543-20161210212019147-1096102686.png
    886543-20161210212028085-1381811239.png
    886543-20161210212036538-784403043.png
  • ret指令将栈顶弹给%eip:
    886543-20161210212145101-1504135682.png
    886543-20161210212155132-1904607023.png
    886543-20161210212205335-1644820451.png
  • 因为函数f修改了%esp,所以用leave指令恢复。leave指令先将%esp对其到%ebp,然后把栈顶弹给%ebp:
    886543-20161210212244194-1407131639.png
    886543-20161210212253085-1181583740.png
    886543-20161210212301382-2032815235.png
    886543-20161210212313663-1886178925.png
    886543-20161210212324694-1791696238.png
    886543-20161210212336663-2083535103.png
  • 主函数汇编代码:
    886543-20161210212407210-1664847960.png
    886543-20161210212427804-1037211629.png
    886543-20161210212444179-1570933439.png
    886543-20161210212504710-2037158711.png
    886543-20161210212510335-1977716444.png

序号汇编代码%eip%ebp%esp%eax
0001movl $0x8,(%esp)0x80483e20xbffff2d80xbffff2d40x1
0002call 0x80483c40x80483e90xbffff2d80xbffff2d40x1
0003push %ebp0x80483c40xbffff2d80xbffff2d00x1
0004move %esp,%ebp0x80483c50xbffff2d80xbffff2cc0x1
0005sub $0x4,%esp0x80483c70xbffff2cc0xbffff2cc0x1
0006mov 0x804a014%eax0x80483c40xbffff2cc0xbffff2c80x1
0007add 0x8(%ebp),%eax0x80483cf0xbffff2cc0xbffff2cc0x2
0008mov %eax,(%esp)0x80483d20xbffff2cc0xbffff2c80xa
0009call 0x80483b40x80483d50xbffff2cc0xbffff2c80xa
0010push %ebp0x80483b40xbffff2cc0xbffff2c40xa
0011mov %esp,%ebp0x80483b50xbffff2cc0xbffff2c00xa
0012movzwl 0x8048010,%eax0x80483b70xbffff2c00xbffff2c00xa
0013cwtl0x80483be0xbffff2c00xbffff2c00x1
0014add 0x8(%ebp),%eax0x80483bf0xbffff2c00xbffff2c00x1
0015pop %ebp0x80483c20xbffff2c00xbffff2c00x1
0016ret0x80483c30xbffff2cc0xbffff2c40xb
0017leave0x80483da0xbffff2cc0xbffff2c80xb
0018ret0x80483db0xbffff2d80xbffff2d00xb
0019mov 0x80484d0,%edx0x80483ee0xbffff2d80xbffff2d40xb
0020add %edx,%eax0x80483f40xbffff2d80xbffff2d40xb
0021leave0x80483f60xbffff2d80xbffff2d40xe
序号汇编代码堆栈
0001movl $0x8,(%esp)0x0
0002call 0x80483c40x8 0x0
0003push %ebp0x80483ee 0x8 0x0
0004move %esp,%ebp0xbffff2d8 0x80483ee 0x8
0005sub $0x4,%esp0xbffff2d8 0x80483ee 0x8
0006mov 0x804a014%eax0xbffff2d8 0x80483ee 0x8
0007add 0x8(%ebp),%eax0x8048409 0xbffff2d8 0x8 0x0
0008mov %eax,(%esp)0x8048409 0xbffff2d8 0x8 0x0 0x14c4d3
0009call 0x80483b40xa 0xbffff2d8 0x80483ee 0x0 0x14c4d3
0010push %ebp0x80483da 0xa 0xbffff2d8 0x8 0x0
0011mov %esp,%ebp0xbffff2cc 0x80483da 0xa 0x80483ee 0x8 0x0
0012movzwl 0x8048010,%eax0xbffff2cc 0x80483da 0xa 0x80483ee 0x8 0x0
0013cwtl0xbffff2cc 0x80483da 0xa 0x80483ee 0x8 0x0
0014add 0x8(%ebp),%eax0xbffff2cc 0x80483da 0xa 0x80483ee 0x8 0x0
0015pop %ebp0xbffff2cc 0x80483da 0xa 0x80483ee 0x8 0x0
0016ret0x80483da 0xa 0xbffff2d8 0x8 0x0
0017leave0xa 0xbffff2d8 0x80483ee 0x0
0018ret0x80483ee 0x8 0x0
0019mov 0x80484d0,%edx0x8 0x0
0020add %edx,%eax0x0
0021leave0x0
posted on 2016-12-10 22:55 20145337马月 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/5337my/p/6158621.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值