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

20145239 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编译

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

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

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

  • 首先,结合display命令和寄存器或pc内部变量,输入display /i $pc、display /i $esp、display /i $ebp。这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。下面展示每一步时%esp%ebp和堆栈内容的变化。
  • call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:

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

  • 先为传参做准备:

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

  • f函数的汇编代码:

  • 实参入栈:

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

  • 计算short+int:

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

  • ret指令将栈顶弹给%eip

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

  • 主函数汇编代码:

 

 

指令%esp%ebp%eip%eax堆栈
push $0x8 0xffffefb8 0xffffefb80x804840b-1345009320x0
call 0x80483ef0xffffcf940xffffcf980x804840b-1345009320x8 0x0
push %ebp0xffffcf900xffffcf980x80483ef-1345009320x8048412 0x8 0x0
mov %esp,%ebp0xffffcf8c0xffffcf980x80483f0-1345009320xffffcf98 0x8048412 0x8 0x0
mov 0x804a01c,%edx0xffffcf8c0xffffcf8c0x80483f2-1345009320xffffcf98 0x8048412 0x8 0x0
mov 0x8(%ebp),%eax0xffffcf8c0xffffcf8c0x80483f8-1345009320xffffcf98 0x8048412 0x8 0x0
add %edx,%eax0xffffcf8c0xffffcf8c0x80483fb80xffffcf98 0x8048412 0x8 0x0
push %eax0xffffcf8c0xffffcf8c0x80483fd100xffffcf98 0x8048412 0x8 0x0
call 0x80483db0xffffcf880xffffcf8c0x80483fe100xa 0xffffcf98 0x8048412 0x8 0x0
push %ebp0xffffcf840xffffcf8c0x80483db100x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
mov %esp,%ebp0xffffcf800xffffcf8c0x80483dc100xffffcf8c 0x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
movzwl 0x804a018,%eax0xffffcf800xffffcf800x80483de100xffffcf8c 0x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
movswl %ax,%edx0xffffcf800xffffcf800x80483e510xffffcf8c 0x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
mov 0x8(%ebp),%eax0xffffcf800xffffcf800x80483e810xffffcf8c 0x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
add %edx,%eax0xffffcf800xffffcf800x80483eb100xffffcf8c 0x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
pop %ebp0xffffcf800xffffcf800x80483ed110xffffcf8c 0x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
ret0xffffcf840xffffcf8c0x80483ee110x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
add $0x4,%esp0xffffcf880xffffcf8c0x8048403110x8048403 0xa 0xffffcf98 0x8048412 0x8 0x0
leave0xffffcf8c0xffffcf8c0x8048406110xffffcf98 0x8048412 0x8 0x0
ret0xffffcf900xffffcf980x8048407110x8048412 0x8 0x0
add $0x4,%esp0xffffcf940xffffcf980x8048412110x8 0x0
mov $0x3,%edx0xffffcf980xffffcf980x8048415110x0
add %edx,%eax0xffffcf980xffffcf980x804841a110x0
leave0xffffcf980xffffcf980x804841c140x0
ret0xffffcf9c0x00x804841d14

 

转载于:https://www.cnblogs.com/dwc929210354/p/6131143.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值