GDB调试汇编堆栈过程分析

本文介绍如何使用gcc和gdb工具进行C语言程序的32位汇编代码生成及调试过程。主要内容包括设置断点、查看寄存器状态、跟踪函数调用流程等,适合初学者学习C语言与底层汇编的交互方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

教材学习内容总结

这是我的C源文件:
1011241-20161218124937245-984713645.png
使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器:
1011241-20161218125021261-2028975288.png
进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值:
1011241-20161218125055183-729234134.png
1011241-20161218125114511-1453146256.png
可见此时主函数的栈基址为0xffffd008
1011241-20161218125252839-1046075746.png

首先,结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。下面展示每一步时%esp、%ebp和堆栈内容的变化:
1011241-20161218125346511-656807265.png
call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
1011241-20161218125418604-1195556972.png
将上一个函数的基址入栈,从当前%esp开始作为新基址:
1011241-20161218125457276-662924593.png
先为传参做准备:
1011241-20161218125527776-1485887975.png
实参的计算在%eax中进行:
1011241-20161218125609589-256615500.png
f函数的汇编代码:
1011241-20161218125722933-1917554554.png
实参入栈:
1011241-20161218125758979-1715056774.png
call指令将下一条指令的地址入栈:
1011241-20161218125947683-1929890700.png
1011241-20161218130000058-1097883357.png
计算short+int:
1011241-20161218130121370-980186277.png
pop %ebp指令将栈顶弹到%ebp中,同时%esp增加4字节:
1011241-20161218130159558-1278789477.png
ret指令将栈顶弹给%eip:
1011241-20161218130225073-1472167685.png
因为函数f修改了%esp,所以用leave指令恢复。leave指令先将%esp对其到%ebp,然后把栈顶弹给%ebp:
1011241-20161218130314433-196096707.png
1011241-20161218130324667-231385125.png
主函数汇编代码:
1011241-20161218130359526-1632295647.png
1011241-20161218130418464-1591775500.png

代码调试中的问题和解决过程

使用-m32指令时报错
用命令sudo apt-get install libc6-dev-i386
1011241-20161218130543526-1664239771.png

指令%esp%ebp堆栈
push $0x80xffffd0680xffffd0680x0
call 0x80483ef0xffffd0640xffffd0680x8 0x0
push %ebp0xffffd0600xffffd0680x8048412 0x8 0x0
mov %esp,%ebp0xffffd05c0xffffd0680xffffd068 0x8048412 0x8 0x0
mov 0x804a01c,%edx0xffffd05c0xffffd05c0xffffd068 0x8048412 0x8 0x0
call 0x80483db0xffffd0580xffffd05c0xa 0xffffd068 0x8048412 0x8 0x0
push %ebp0xffffd0540xffffd05c0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
mov %esp,%ebp0xffffd0500xffffd05c0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
movzwl 0x804a018,%eax0xffffd0500xffffd0500xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
ret0xffffd0540xffffd05c0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
leave0xffffd05c0xffffd05c0xffffd068 0x8048412 0x8 0x0
ret0xffffd0600xffffd0680x8048412 0x8 0x0
add $0x4,%esp0xffffd0640xffffd0680x8 0x0
mov $0x3,%edx0xffffd0680xffffd0680x0
ret

转载于:https://www.cnblogs.com/liuyiyang/p/6194280.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值