GDB调试汇编堆栈过程分析

分析过程

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

2 使用gdb调试代码。

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

885288-20161205001330646-202113518.jpg

885288-20161205001036756-2080517752.jpg

885288-20161205001600631-455474584.jpg

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

885288-20161205001435912-2091947324.jpg

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

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

885288-20161205001517818-1941301555.jpg

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

885288-20161205001545537-334698297.jpg

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

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

885288-20161205001822177-547253554.jpg

885288-20161205001959974-891847993.jpg

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

885288-20161205002136349-55119063.jpg

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

885288-20161205002337537-1780899307.jpg

9 f函数的汇编代码:

885288-20161205002625115-1339445882.jpg

10 实参入栈:

885288-20161205003242131-155298047.jpg

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

885288-20161205003412381-1376877459.png

13 计算short+int:

885288-20161205003455459-1208784167.png

885288-20161205003503177-1328820638.png

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

885288-20161205003535224-809989941.png

885288-20161205003542209-1587496439.png

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

885288-20161205003613224-1688930632.png

汇编代码及分析:

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

转载于:https://www.cnblogs.com/HZW20145322/p/6132418.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值