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调试器

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

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

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

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

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

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

  • 首先,结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。下面展示每一步时%esp%ebp和堆栈内容的变化:

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

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

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

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

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

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

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

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

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

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

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

  • 先为传参做准备:

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

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

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

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

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

  • f函数的汇编代码:

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

  • 实参入栈:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 计算short+int:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 因为函数f修改了%esp,所以用leave指令恢复。leave指令先将%esp对其到%ebp,然后把栈顶弹给%ebp:

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

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

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

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

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

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

  • 主函数汇编代码:

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

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

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

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

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

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
04-20 14:30
查看更多