BUPT CSAPP lab1

一、实验目的
1、熟悉linux操作的基本操作;
2、掌握gcc编译方法;
3、掌握gdb的调试工具使用;
4、掌握objdump反汇编工具使用;
5、熟悉理解反汇编程序(对照源程序与objdump生成的汇编程序)。
二、实验环境
列举你所使用的软件工具
1、Xshell软件
2、vi编辑器
3、gcc编译工具
4、gdb调试工具
5、objdump反汇编工具
实验环境为Linux
三、实验内容
现有int型数组a[i]=i-50,b[i]=i+y,其中y取自于学生本人学号2020211472的个位。登录bupt1服务器,在linux环境下使用vi编辑器编写C语言源程序,完成数组a+b的功能,规定数组长度为100,函数名为madd(),数组a,b均定义在函数内,采用gcc编译该程序(使用-g选项,但不使用优化选项),
1、使用objdump工具生成汇编程序,找到madd函数的汇编程序,给出截图;
2、用gdb进行调试,练习如下gdb命令,给出截图;
gdb、file、kill、quit、break、delete、clear、info break、run、continue、nexti、stepi、disassemble、list、print、x、info reg、watch
3、找到a[i]+b[i]对应的汇编指令,指出a[i]和b[i]位于哪个寄存器中,给出截图;
4、使用单步指令及gdb相关命令,显示a[xy]+b[xy]对应的汇编指令执行前后操作数寄存器十进制和十六进制的值,其中x,y取自于学生本人学号2020211472的百位和个位。
学号2019211999,a[99]+b[99]单步执行前后的参考截图如下(实际命令未显示出):
在这里插入图片描述
四、实验步骤及实验分析
准备工作:登录服务器,进入Linux系统,新建子目录lab1,通过vi编辑器新建C源文件add.c,并编写c语言程序。保存并退出。使用ls命令检查lab1目录下的文件,采用gcc编译add.c程序(使用-g选项)。使用ls命令检查是否产生a.out文件。
过程如下图:
在这里插入图片描述
在这里插入图片描述

1、使用objdump工具生成汇编程序,找到madd函数的汇编程序,给出截图
操作如下:使用objdump命令,-d选项
在这里插入图片描述
找到madd函数,即在汇编语言中找到
madd函数汇编程序如下:
在这里插入图片描述
2.使用gdb进行调试,练习各种命令,
gdb:键入gdb,如下图
在这里插入图片描述
file:键入 file a.out,开始加载程序 如下图
在这里插入图片描述
kill:键入 kill ,终止当前正在调试的程序 如下图
在这里插入图片描述
quit:键入 quit ,退出gdb调试程序,此时回到目录lab1 如下图
在这里插入图片描述
重新进入gdb调试程序,练习以下命令
break: 键入break madd,在madd函数处设置一个断点
键入break 8,在第八行设置一个断点
键入break 9,在第九行设置一个断点
键入break 10,在第十行设置一个断点
在这里插入图片描述

delete:键入delete 1,删除编号为1的断点(即在madd函数处的断点)
键入info break显示当前断点信息
在这里插入图片描述

clear:先通过命令run和n,使程序运行至第九行,随后键入clear,删除第九行的断点,即二号断点,后键入info break显示当前断点信息
在这里插入图片描述

info break:键入info break,显示当前断点信息
在这里插入图片描述

run:(此处使用练习clear命令时使用的run命令效果图)
在这里插入图片描述

continue:键入continue,程序运行到下一个断点
在这里插入图片描述

nexti:键入nexti,程序以函数调用为单位执行一条指令,接下来给出使用三次nexti命令的运行截图
在这里插入图片描述

stepi:键入stepi,程序以函数调用为单位执行一条指令,接下来给出使用三次stepi命令的运行截图,可看出此时stepi功能与nexti类似。
在这里插入图片描述
disassemble:键入disassemble,显示当前函数的汇编代码,由于程序正在此函数中运行,故需要在中断后根据提示键入c继续显示完整汇编代码
观察当前代码,可发现其与objdump得到的结果有共同点
在这里插入图片描述

list:键入list 1,从程序起始处开始显示10行代码
再键入list,显示11-18行代码(程序共18行)
注:若直接键入list,将显示从程序当前停留语句开始的代码
下图给出上述两种情况
在这里插入图片描述

print:键入print a[0],显示a[0]的值,其他变量亦同
注:此时,未进行第一次a[i]=a[i]+b[i],a[0]的值仍为0-50=-50
在这里插入图片描述

x:键入 print x &b[0],显示存储b[0]的地址内的值,表现为十六进制
在这里插入图片描述

info reg: 键入info reg ,显示当前各寄存器内的值
从下图可发现,%rdx内存有和a[0]相等的值,%rax内存有和b[0]相等的值。
在这里插入图片描述

watch:键入watch a[42] 监视a[42]的变化
在这里插入图片描述

使用continue命令,直到a[42]发生变化
下图中,a[42]第一次发生变化为a[i]=i-50;
第二次发生变化为a[i]=a[i]+b[i];
在这里插入图片描述

3.寻找a[i]+b[i]对应的汇编指令
使用gdb调试命令,重新开始程序,设置断点
当前程序断点为:
在这里插入图片描述

使用run命令和continue命令,使程序运行至a[i]=a[i]+b[i]
在这里插入图片描述

后使用disassemble命令查看当前函数汇编指令(即madd函数汇编指令)
可发现a[i]+b[i]的对应汇编语句为:
在这里插入图片描述

故 a[i]寄存器%edx(即%rdx的低32位)中,b[i]在寄存器%eax(即%rax低32位)中,
4. 学生学号2020211472,故x=4,y=2,xy=42
现在给出a[42]+b[42]运行前后的指令
通过disassemble命令得到汇编指令,确认a[42]+b[42]即将运行
运行a[42]+b[42]语句:
在这里插入图片描述
运行后第一句:
在这里插入图片描述
随后输出a[42]+b[42]对应的汇编指令执行前后操作数寄存器十进制和十六进制的值
使用print $寄存器名 输出寄存器内值的十进制形式
使用print /x $寄存器名 输出寄存器内值的十六进制形式
在这里插入图片描述

从上图可看出,以数的十进制形式为例,运行对应指令后,寄存器%edx内的值由-8变为36。寄存器%eax内的值不变。显示%edx内的值经过add指令,加上了寄存器%eax内的值,进而a[42]的值由-8变成36,表明执行了C语言语句a[42]=a[42]+b[42]的汇编指令中对应的加法操作语句。

  • 22
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值