您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 计算机系统第三章答案
习题3.参考答案:(1)后缀:w,源:基址+比例变址+偏移,目:寄存器(2)后缀:b,源:寄存器,目:基址+偏移(3)后缀:l,源:比例变址,目:寄存器(4)后缀:b,源:基址,目:寄存器(5)后缀:l,源:立即数,目:栈(6)后缀:l,源:立即数,目:寄存器(7)后缀:w,源:寄存器,目:寄存器(8)后缀:l,源:基址+变址+偏移,目:寄存器4.参考答案:(1)源操作数是立即数0xFF,需在前面加‘$’(2)源操作数是16位,而长度后缀是字节‘b’,不一致(3)目的操作数不能是立即数寻址(4)操作数位数超过16位,而长度后缀为16位的‘w’(5)不能用8位寄存器作为目的操作数地址所在寄存器(6)源操作数寄存器与目操作数寄存器长度不一致(7)不存在ESX寄存器(8)源操作数地址中缺少变址寄存器5.参考答案:表3.12题5用表src_typedst_type机器级表示charintmovsbl%al,(%edx)intcharmovb%al,(%edx)intunsignedmovl%eax,(%edx)shortintmovswl%ax,(%edx)unsignedcharunsignedmovzbl%al,(%edx)charunsignedmovsbl%al,(%edx)intintmovl%eax,(%edx)6.参考答案:(1)xptr、yptr和zptr对应实参所存放的存储单元地址分别为:R[ebp]+8、R[ebp]+12、R[ebp]+16。(2)函数func的C语言代码如下:voidfunc(int*xptr,int*yptr,int*zptr){inttempx=*xptr;inttempy=*yptr;inttempz=*zptr;*yptr=tempx;*zptr=tempy;*xptr=tempz;}7.参考答案:(1)R[edx]=x(2)R[edx]=x+y+4(3)R[edx]=x+8*y(4)R[edx]=y+2*x+12(5)R[edx]=4*y(6)R[edx]=x+y8.参考答案:(1)指令功能为:R[edx]←R[edx]+M[R[eax]]=0x00000080+M[0x8049300],寄存器EDX中内容改变。改变后的内容为以下运算的结果:00000080H+FFFFFFF0H因此,EDX中的内容改变为0x00000070。根据表3.5可知,加法指令会影响OF、SF、ZF和CF标志。OF=0,ZF=0,SF=0,CF=1。(2)指令功能为:R[ecx]←R[ecx]-M[R[eax]+R[ebx]]=0x00000010+M[0x8049400],寄存器ECX中内容改变。改变后的内容为以下运算的结果:00000010H-80000008H因此,ECX中的内容改为0x80000008。根据表3.5可知,减法指令会影响OF、SF、ZF和CF标志。OF=1,ZF=0,SF=1,CF=10=1。(3)指令功能为:R[bx]←R[bx]orM[R[eax]+R[ecx]*8+4],寄存器BX中内容改变。改变后的内容为以下运算的结果:0x0100orM[0x8049384]=0100HorFF00H因此,BX中的内容改为0xFF00。由3.3.3节可知,OR指令执行后OF=CF=0;因为结果不为0,故ZF=0;因为最高位为1,故SF=1。(4)test指令不改变任何通用寄存器,但根据以下“与”操作改变标志:R[dl]and0x80由3.3.3节可知,TEST指令执行后OF=CF=0;因为结果不为0,故ZF=0;因为最高位为1,故SF=1。(5)指令功能为:M[R[eax]+R[edx]]←M[R[eax]+R[edx]]*32,即存储单元0x8049380中的内容改变为以下运算的结果:M[0x8049380]*32=0x908f12a8*32,也即只要将0x908f12a8左移5位即可得到结果。100100001000111100010010101010005=00010001111000100101010100000000因此,指令执行后,单元0x8049380中的内容改变为0x11e25500。显然,这个结果是溢出的。但是,根据表3.5可知,乘法指令不影响标志位,也即并不会使OF=1。100000001000000010000000andd000000010000000011111111000000001111111100000000or0000000000000000000000000001000001111111111111111111111111111000010000000000000000000000000001000+0000000000000000000000001000000011111111111111111111111111110000100000000000000000000000001110000+(6)指令功能为:R[cx]←R[cx]-1,即CX寄存器的内容减一。因此,指令执行后CX中的内容从0x0010变为0x000F。由表3.5可知,DEC指令会影响OF、ZF、SF,根据上述运算结果,得到OF=0,ZF=0,SF=0。9.参考答案:movl12(%ebp),%ecx//R[ecx]←M[R[ebp]+12],将y送ECXsall$8,%ecx//R[ecx]←R[ecx]8,将y*256送ECXmovl8(%ebp),%eax//R[eax]←M[R[ebp]+8],将x送EAXmovl20(%ebp),%edx//R[edx]←M[R[ebp]+20],将k送EDXimull%edx,%eax//R[eax]←R[eax]*R[edx],将x*k送EAXmovl16(%ebp),%edx//R[edx]←M[R[ebp]+16],将z送EDXandl$65520,%edx//R[edx]←R[edx]and65520,将z&0xFFF0送EDXaddl%ecx,%edx//R[edx]←R[edx]+R[ecx],将z&0xFFF0+y*256送EDXsubl%edx,%eax//R[eax]←R[eax]-R[edx],将x*k-(z&0xFFF0+y*256)送EAX根据以上分析可知,第3行缺失部分为:3intv=x*k-(z&0xFFF0+y*256);10.参考答案:从汇编代码的第2行和第4行看,y应该是占8个字节,R[ebp]+20开始的4个字节为高32位字节,记为yh;R[ebp]+16开始的4个字节为低32位字节,记为yl。根据第4行为无符号数乘法指令,得知y的数据类型num_type为unsignedlonglong。movl12(%ebp),%eax//R[eax]←M[R[ebp]+12],将x送EAXmovl20(%ebp),%ecx//R[ecx]←M[R[ebp]+20],将yh送ECXimull%eax,%ecx//R[ecx]←R[ecx]*R[eax],将yh*x的低32位送ECXmull16(%ebp)//R[edx]R[eax]←M[R[ebp]+16]*R[eax],将yl*x送EDX-EAXleal(%ecx,%edx),%edx//R[edx]←R[ecx]+R[edx],将yl*x的高32位与yh*x的低32位相加后送EDXmovl8(%ebp),%ecx//R[ecx]←M[R[ebp]+8],将d送ECXmovl%eax,(%ecx)//M[R[ecx]]←R[eax],将x*y低32位送d指向的低32位movl%edx,4(%ecx)//M[R[ecx]+4]←R[edx],将x*y高32位送d指向的高32位11.参考答案:根据第3.3.4节得知,条件转移指令都采用相对转移方式在段内直接转移,即条件转移指令的转移目标地址为:(PC)+偏移量。(1)因为je指令的操作码为01110100,所以机器代码7408H中的08H是偏移量,故转移目标地址为:0x804838c+2+0x8=0x8048396。call指令中的转移目标地址0x80483b1=0x804838e+5+0x1e,由此,可以看出,call指令机器代码中后面的4个字节是偏移量,因IA-32采用小端方式,故偏移量为0000001EH。call指令机器代码共占5个字节,因此,下条指令的地址为当前指令地址0x804838e加5。(2)jb指令中F6H是偏移量,故其转移目标地址为:0x8048390+2+0xf6=0x8048488。movl指令的机器代码有10个字节,前两个字节是操作码等,后面8个字节为两个立即数,因为是小端方式,所以,第一个立即数为0804A800H,即汇编指令中的目的地址0x804a800,最后4个字节为立即数00000001H,即汇编指令中的常数0x1。0000000000010000111111111111111110000000000001111+(3)jle指令中的7EH为操作码,16H为偏移量,其汇编形式中的0x80492e0是转移目的地址,因此,假定后面的mov指令的地址为x,则x满足以下公式:0x80492e0=x+0x16,故x=0x80492e0-0x16=0x80492ca。(4)jmp指令中的E9H为操作码,后面4个字节为偏移量,因为是小端方式,故偏移量为FFFFFF00H,即-100H=-256。后面的sub指令的地址为0x804829b,故jmp指令的转移目标地址为0x804829b+0xffffff00=0x804829b-0x100=0x804819b。12.参考答案:(1)汇编指令的注解说明如下:1movb8(%ebp),%dl//R[dl]←M[R[ebp]+8],将x送DL2movl12(%ebp),%eax//R[eax]←M[R[ebp]+12],将p送EAX3testl%eax,%eax//R[eax]andR[eax],判断p是否为04je.L1//若p为0,则转.L1执行5testb$0x80,%dl//R[dl]and80H,判断x的第一位是否为06je.L1//若x=0,则转.L1执行7addb%dl,(%eax)//M[R[eax]]←M[R[eax]]+R[dl],即*p+=x8.L1:因为C语言if语句中的条件表达式可以对多个条件进行逻辑运算,而汇编代码中一条指令只能进行一种逻辑运算,并且在每条逻辑运算指令生成的标志都是存放在同一个EFLAGS寄存器中,所以,最好在一条逻辑指令后跟一条条件转移指令,把EFLAGS中标志用完,然后再执行另一次逻辑判断并根据条件进行转移的操作。(2)按照书中图3.22给出的“if()goto…”语句形式写出汇编代码对应的C语言代码如下:1voidcomp(charx,int*p)2{3if(p!=0)4if(x0)5*p+=x;6}13.参考答案:1intfunc(intx,inty)2{3intz=x*y;4if(x=-100){5if(yx)6z=x+y;7else8z=x-y;9}elseif(x=16)10z=x&y;11returnz;12}14.参考答案:(1)每个入口参数都要按4字节边界对齐,因此,参数x、y和k入栈时都占4个字节。1movw8(%ebp),%bx//R[bx]←M[R[ebp]+8],将x送BX2movw12(%ebp),%si//R[si]←M[R[ebp]+12],将y送SI3movw16(%ebp),%cx//R[cx]←M[R[ebp]+16],将k送CX4.L1:5movw%si,%dx//R[dx]←R[si],将y送DX6movw%dx,%ax//R[ax]←R[dx],将y送AX7sarw$15,%dx//R[dx]←R[dx]15,将y的符号扩展16位送DX8idiv%cx//R[dx]←R[dx-ax]÷R[cx]的余数,将y%k送DX//R[ax]←R[d
本文标题:计算机系统第三章答案
链接地址:https://www.777doc.com/doc-2399549 .html