华中科技大学计算机系统基础实验报告.docx
- 文档编号:18356914
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:32
- 大小:1.50MB
华中科技大学计算机系统基础实验报告.docx
《华中科技大学计算机系统基础实验报告.docx》由会员分享,可在线阅读,更多相关《华中科技大学计算机系统基础实验报告.docx(32页珍藏版)》请在冰点文库上搜索。
华中科技大学计算机系统基础实验报告
课程实验报告
课程名称:
计算机系统基础
专业班级:
学号:
姓名:
指导教师:
报告日期:
2016年5月24日
计算机科学与技术学院
实验1:
数据表示
1.1实验概述
本实验的目的是更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。
实验中,你需要解开一系列编程“难题”——使用有限类型和数量的运算操作实现一组给定功能的函数,在此过程中你将加深对数据二进制编码表示的了解。
实验语言:
c;实验环境:
linux
1.2实验容
需要完成bits.c中下列函数功能,具体分为三大类:
位操作、补码运算和浮点数操作。
1.3实验设计
源码如下:
/*
*lsbZero-set0totheleastsignificantbitofx
*Example:
lsbZero(0x87654321)=0x87654320
*Legalops:
!
~&^|+<<>>
*Maxops:
5
*Rating:
1
*/
intlsbZero(intx){
//x右移一位再左移一位实现把最低有效位置0
x=x>>1;
x=x<<1;
returnx;
}
/*
*byteNot-bit-inversiontobytenfromwordx
*Bytesnumberedfrom0(LSB)to3(MSB)
*Examples:
getByteNot(0x12345678,1)=0x1234A978
*Legalops:
!
~&^|+<<>>
*Maxops:
6
*Rating:
2
*/
intbyteNot(intx,intn){
//x第n个字节每位都和1异或实现取反
inty=0xff;
n=n<<3;
y=y< x=(x^y); returnx; } /* *byteXor-comparethenthbyteofxandy,ifitissame,return0,ifnot,return1 *example: byteXor(0x12345678,0x87654321,1)=1 *byteXor(0x12345678,0x87344321,2)=0 *Legalops: ! ~&^|+<<>> *Maxops: 20 *Rating: 2 */ intbyteXor(intx,inty,intn){ //把x和y的第n个字节取出来异或,再转换为逻辑的0和1 n=n<<3; x=x>>n; y=y>>n; x=x&(0xff); y=y&(0xff); return! ! (x^y); } /* *logicalAnd-x&&y *Legalops: ! ~&^|+<<>> *Maxops: 20 *Rating: 3 */ intlogicalAnd(intx,inty){ //把x和y分别转化为逻辑的0和1,再相与 x=(! (! x))&(! (! y)); returnx; } /* *logicalOr-x||y *Legalops: ! ~&^|+<<>> *Maxops: 20 *Rating: 3 */ intlogicalOr(intx,inty){ //把x和y分别转化为逻辑的0和1,再相或 x=(! (! x))|(! (! y)); returnx; } /* *rotateLeft-Rotatextotheleftbyn *Canassumethat0<=n<=31 *Examples: rotateLeft(0x87654321,4)=0x76543218 *Legalops: ~&^|+<<>>! *Maxops: 25 *Rating: 3 */ introtateLeft(intx,intn){ //先构造低n位为1,高(32-n)位为0的数z,x左移n位后的数加上x右移(32-n)位的数&z即可 intz; z=~(((1<<31)>>31)< x=((x>>(32+(~n+1)))&z)+(x< returnx; } /* *parityCheck-returns1ifxcontainsanoddnumberof1's *Examples: parityCheck(5)=0,parityCheck(7)=1 *Legalops: ! ~&^|+<<>> *Maxops: 20 *Rating: 4 */ intparityCheck(intx){ //每次将数的低半数位与高半数位比较,再把y右移31位,最后把y转化为逻辑的0和1 inty; y=x<<16; y=y^x; y=y^(y<<8); y=y^(y<<4); y=y^(y<<2); y=y^(y<<1); y=y>>31; return! (! y); } /* *mul2OK-Determineifcancompute2*xwithoutoverflow *Examples: mul2OK(0x30000000)=1 *mul2OK(0x40000000)=0 * *Legalops: ~&^|+<<>> *Maxops: 20 *Rating: 2 */ intmul2OK(intx){ //把x第31位和30位分别和1做按位与,再异或,再和1异或 intm; m=((x>>31)&0x1)^((x>>30)&0x1); returnm^0x1; } /* *mult3div2-multipliesby3/2roundingtoward0, *ShouldexactlyduplicateeffectofCexpression(x*3/2), *includingoverflowbehavior. *Examples: mult3div2(11)=16 *mult3div2(-9)=-13 *mult3div2(1073741824)=-536870912(overflow) *Legalops: ! ~&^|+<<>> *Maxops: 12 *Rating: 2 */ intmult3div2(intx){ //左移一位再+x即x*3,右移一位的时候,当y的最高位和最低位都为0时还要+1 inty=(x<<1)+x; y=(y>>1)+(((y>>31)&1)&(((y<<31)>>31)&1)); returny; } /* *subOK-Determineifcancomputex-ywithoutoverflow *Example: subOK(0x80000000,0x80000000)=1, *subOK(0x80000000,0x70000000)=0, *Legalops: ! ~&^|+<<>> *Maxops: 20 *Rating: 3 */ intsubOK(intx,inty){ //x的最高有效位和y的最高有效位不同且x和(x-y)的最高位不同才能判断溢出 intm=(x>>31)&1; intn=(y>>31)&1; x=(m^n)&(m^(((x+(~y+1))>>31)&1)); return(! x); } /* *absVal-absolutevalueofx *Example: absVal(-1)=1. *Youmayassume-TMax<=x<=TMax *Legalops: ! ~&^|+<<>> *Maxops: 10 *Rating: 4 */ intabsVal(intx){ //x最高位为0时就是x,最高位为1时是~x+1 inty=x>>31; x=(y&(~x+1))+((~y)&x); returnx; } /* *float_abs-Returnbit-levelequivalentofabsolutevalueofffor *floatingpointargumentf. *Boththeargumentandresultarepassedasunsignedint's,but *theyaretobeinterpretedasthebit-levelrepresentationsof *single-precisionfloatingpointvalues. *WhenargumentisNaN,returnargument.. *Legalops: Anyinteger/unsignedoperationsincl.||,&&.alsoif,while *Maxops: 10 *Rating: 2 */ unsignedfloat_abs(unsigneduf){ intx=uf&(~(1<<31)); if(x>0x7f800000) { returnuf; } elsereturnx; } /* *float_f2i-Returnbit-levelequivalentofexpression(int)f *forfloatingpointargumentf. *Argumentispassedasunsignedint,but *itistobeinterpretedasthebit-levelrepresentationofa *single-precisionfloatingpointvalue. *Anythingoutofrange(includingNaNandinfinity)shouldreturn *0x80000000u. *Legalops: Anyinteger/unsignedoperationsincl.||,&&.alsoif,while *Maxops: 30 *Rating: 4 */ intfloat_f2i(unsigneduf){ unsignednum=0x80000000; intx=(uf&0x007fffff)^0x00800000; intorder=0; order=(uf&0x7f800000)>>23; if(order>158){ returnnum; } if(order<127)return0; elseif(((uf>>31)&1)==1){ if(order>150){ return~(x<<(order-150))+1; } elsereturn~(x>>(150-order))+1; } else{ if(order>150)returnx<<(order-150); elsereturnx>>(150-order); } } 1.4实验过程 编写源码,运行btest,得出实验结果。 1.5实验结果 可见13个函数全部正确。 1.6实验小结 此次实验主要考查的是对数据的处理,对此需要掌握数据在机器中的表示,运用合理的位运算来实现相应的功能。 实验2: BinaryBombs 2.1实验概述 本实验中,你要使用课程所学知识拆除一个“binarybombs”来增强对程序的机器级表示、汇编语言、调试器和逆向工程等方面原理与技能的掌握。 一个“binarybombs”(二进制炸弹,下文将简称为炸弹)是一个Linux可执行C程序,包含了6个阶段(phase1~phase6)。 炸弹运行的每个阶段要求你输入一个特定的字符串,若你的输入符合程序预期的输入,该阶段的炸弹就被“拆除”,否则炸弹“爆炸”并打印输出"BOOM! ! ! "字样。 实验的目标是拆除尽可能多的炸弹层次。 每个炸弹阶段考察了机器级语言程序的一个不同方面,难度逐级递增: *阶段1: 字符串比较 *阶段2: 循环 *阶段3: 条件/分支 *阶段4: 递归调用和栈 *阶段5: 指针 *阶段6: 链表/指针/结构 另外还有一个隐藏阶段,但只有当你在第4阶段的解之后附加一特定字符串后才会出现。 为了完成二进制炸弹拆除任务,你需要使用gdb调试器和objdump来反汇编炸弹的可执行文件,并单步跟踪调试每一阶段的机器代码,从中理解每一汇编语言代码的行为或作用,进而设法“推断”出拆除炸弹所需的目标字符串。 这可能需要你在每一阶段的开始代码前和引爆炸弹的函数前设置断点,以便于调试。 实验语言: C语言 实验环境: linux 2.2实验容 反汇编bomb,得到汇编代码,根据汇编代码完成拆炸弹任务。 2.2.1阶段1字符串比较 1.任务描述: 找到与输入的字符串进行比较的存储的字符串的首地址,进而得到存储的字符串,得到结果。 2.实验设计: 根据反汇编代码一步一步分析,具体见实验过程。 3.实验过程: 将bomb反汇编输出到asm.txt文件中,在反汇编代码中查找phase_1的位置: 从上面的语句可以看出 得知%eax里存储的是调用read_line()函数后返回的结果,就是输入的字符串,所以得知和用户输入字符串比较的字符串的存储地址为0x804a204,可用gdb查看这个地址存储的数据容: 翻译过后的结果为Thefuturewillbebettertomorrow. 4.实验结果: 可见结果正确。 2.2.2阶段2循环 1.任务描述: 完成炸弹2的拆除 2.实验设计: 观察分析phase_2代码,使用gdb调试分析结果 3.实验过程: 找到phase_2代码: 由read_six_numbers知是要输入6个数字,观察: 可知输入的第一个和第二个必须依次为0,1 观察这两个循环可知只有当输入的数为前两个数之和时才不会bomb,故得到序列0,1,1,2,3,5 4.实验结果: 输入上述序列后得: 可知结果正确。 2.2.3阶段3条件/分支 1.任务描述: 完成炸弹3的拆除 2.实验设计: 观察分析phase_3代码,使用gdb调试分析结果 3.实验过程: 找到phase_3代码如下: 08048c0a 8048c0a: 83ec3csub$0x3c,%esp 8048c0d: 8d44242clea0x2c(%esp),%eax 8048c11: 89442410mov%eax,0x10(%esp) 8048c15: 8d442427lea0x27(%esp),%eax 8048c19: 8944240cmov%eax,0xc(%esp) 8048c1d: 8d442428lea0x28(%esp),%eax 8048c21: 89442408mov%eax,0x8(%esp) 8048c25: c74424044ea204movl$0x804a24e,0x4(%esp) 由此行代码查看输入容: 可知输入的依次是数字、字符、数字 8048c43: 837c242807cmpl$0x7,0x28(%esp) 8048c48: 0f87f5000000ja8048d43 … 8048d43: e88d040000call80491d5 可见输入的第一个数一定小于7 8048c4e: 8b442428mov0x28(%esp),%eax 8048c52: ff248560a20408jmp*0x804a260(,%eax,4) 假设输入的第一个数为0,即(%eax)=0,所以: 8048c59: b876000000mov$0x76,%eax 8048c5e: 817c242c040100cmpl$0x104,0x2c(%esp) 所以第二个字符ascll码为0x76,即字符'v' 而第三个数为0x104,即260 4.实验结果: 从实验结果来看结果正确,拆弹成功。 2.2.4阶段4递归调用和栈 1.任务描述: 拆除炸弹4 2.实验设计: 观察分析phase_4代码,使用gdb调试分析结果 3.实验过程: 用x/sb0x804a3cf来查询有几个输入以及输入的类型,如下所示: 由此可见输入是两个整数。 再由phase_4中: 知道func4第二个参数值为1f,即37 再仔细研究func4函数,发现其实现了递归调用: 08048d5c 8048d5c: 56push%esi 8048d5d: 53push%ebx 8048d5e: 83ec14sub$0x14,%esp 8048d61: 8b542420mov0x20(%esp),%edx/ebx是传递的参数/ 8048d65: 8b442424mov0x24(%esp),%eax 8048d69: 8b742428mov0x28(%esp),%esi 8048d6d: 89f1mov%esi,%ecx 8048d6f: 29c1sub%eax,%ecx 8048d71: 89cbmov%ecx,%ebx 8048d73: c1eb1fshr$0x1f,%ebx/ebx右移31位/ 8048d76: 01d9add%ebx,%ecx 8048d78: d1f9sar%ecx 8048d7a: 8d1c01lea(%ecx,%eax,1),%ebx 8048d7d: 39d3cmp%edx,%ebx 8048d7f: 7e17jle8048d98 8048d81: 8d4bfflea-0x1(%ebx),%ecx 8048d84: 894c2408mov%ecx,0x8(%esp) 8048d88: 89442404mov%eax,0x4(%esp) 8048d8c: 891424mov%edx,(%esp) 8048d8f: e8c8ffffffcall8048d5c 8048d94: 01d8add%ebx,%eax 8048d96: eb1bjmp8048db3 8048d98: 89d8mov%ebx,%eax 8048d9a: 39d3cmp%edx,%ebx 8048d9c: 7d15jge8048db3 8048d9e: 89742408mov%esi,0x8(%esp) 8048da2: 8d4301lea0x1(%ebx),%eax 8048da5: 89442404mov%eax,0x4(%esp) 8048da9: 891424mov%edx,(%esp) 8048dac: e8abffffffcall8048d5c 8048db1: 01d8add%ebx,%eax 8048db3: 83c414add$0x14,%esp 8048db6: 5bpop%ebx 8048db7: 5epop%esi 8048db8: c3ret 下面就来剖析func4,这个函数在确定栈之后,首先取出来传递给它的参数,依次放在eax,edx,esi.中,从一个jle和一个jge可以看出,这个递归函数跳出的条件根据func4的第二个参数和第二个参数进过种种运算的结果等于第一个参数即可。 注意在递归过程中第一个参数是不变的,最后返回值是经过运算后的ebx加上第一个参数。 当时做实验时推出了具体的表达式,未记录下来,只记录了最后得出fun(11)=31。 运行结果如下: 由此可见,phase_4拆除成功! 4.实验结果: 给出阶段x的实验结果和必要的结果分析 2.2.5阶段5phase_5 1.任务描述: 拆除一个关于指针的炸弹。 2.实验设计: 此阶段实验与指针相关,又根据静态调试跟踪可知,需借助gdb的动态调试跟踪来查找相关地址中存放的数据的值,进而分析出最终的拆弹密码。 3.实验过程: 首先观察代码,分析代码时发现有多个跳转指令,具体为x>15时,bomb;x>=1时,取x低4位; 使用gdb调试发现,要输入的是两个%d数。 由后面的步骤知输入第一个数为初始数组下标,第二个数为循环15次累加求的和。 再接着: 8048e70: 8b048580a20408mov0x804a280(,%eax,4),%eax,这句就是从(0x804a280+eax*4)里面拿数据出来,加到eax上。 因为eax只能是0~F的数,所以0x804a260这个地址里面存的应该是一个数据大小为16的数组,用gdb看,得到: 观察到果然是一个数组,然后下面就是把5个输入对应ascll码的低4位转换的十进制数对应的数值一个一个的转化为这个数组,得到累加值ecx。 观察循环部分: 由此知当退出循环的条件是取出的数ea
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 华中科技大学 计算机系统 基础 实验 报告