计算机系统第三章答案剖析.doc
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机系统 第三 答案 剖析
- 资源描述:
-
习 题 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_type dst_type 机器级表示 char int movsbl %al, (%edx) int char movb %al, (%edx) int unsigned movl %eax, (%edx) short int movswl %ax, (%edx) unsigned char unsigned movzbl %al, (%edx) char unsigned movsbl %al, (%edx) int int movl %eax, (%edx) 6.参考答案: (1)xptr、yptr和zptr对应实参所存放的存储单元地址分别为:R[ebp]+8、R[ebp]+12、 R[ebp]+16。 (2)函数func的C语言代码如下: void func(int *xptr, int *yptr, int *zptr) { int tempx=*xptr; int tempy=*yptr; int tempz=*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+y 8.参考答案: (1)指令功能为:R[edx]←R[edx]+M[R[eax]]=0x00000080+M[0x8049300],寄存器EDX中内容改变。改变后的内容为以下运算的结果:00000080H+FFFFFFF0H 0000 0000 0000 0000 0000 0000 1000 0000 1111 1111 1111 1111 1111 1111 1111 0000 1 0000 0000 0000 0000 0000 0000 0111 0000 + 因此,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 0000 0000 0000 0000 0000 0000 0001 0000 0111 1111 1111 1111 1111 1111 1111 1000 0 1000 0000 0000 0000 0000 0000 0000 1000 + 因此,ECX中的内容改为0x80000008。根据表3.5可知,减法指令会影响OF、SF、ZF和CF标志。OF=1,ZF=0,SF=1,CF=1Å0=1。 (3)指令功能为:R[bx]←R[bx] or M[R[eax]+R[ecx]*8+4],寄存器BX中内容改变。改变后的内容为以下运算的结果:0x0100 or M[0x8049384]=0100H or FF00H 0000 0001 0000 0000 1111 1111 0000 0000 1111 1111 0000 0000 or 因此,BX中的内容改为0xFF00。由3.3.3节可知,OR指令执行后OF=CF=0;因为结果不为0,故ZF=0;因为最高位为1,故SF=1。 (4)test指令不改变任何通用寄存器,但根据以下“与”操作改变标志:R[dl] and 0x80 1000 0000 1000 0000 1000 0000 andd 由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位即可得到结果。 1001 0000 1000 1111 0001 0010 1010 1000<<5 =0001 0001 1110 0010 0101 0101 0000 0000 因此,指令执行后,单元0x8049380中的内容改变为0x11e25500。显然,这个结果是溢出的。但是,根据表3.5可知,乘法指令不影响标志位,也即并不会使OF=1。 (6)指令功能为:R[cx] ←R[cx]-1,即CX寄存器的内容减一。 0000 0000 0001 0000 1111 1111 1111 1111 1 0000 0000 0000 1111 + 因此,指令执行后CX中的内容从0x0010变为0x000F。由表3.5可知,DEC指令会影响OF、ZF、SF,根据上述运算结果,得到OF=0,ZF=0,SF=0。 9.参考答案: movl 12(%ebp), %ecx //R[ecx]←M[R[ebp]+12],将y送ECX sall $8, %ecx //R[ecx]←R[ecx]<<8,将y*256送ECX movl 8(%ebp), %eax //R[eax]←M[R[ebp]+8],将x送EAX movl 20(%ebp), %edx //R[edx]←M[R[ebp]+20],将k送EDX imull %edx, %eax //R[eax]←R[eax]*R[edx],将x*k送EAX movl 16(%ebp), %edx //R[edx]←M[R[ebp]+16],将z送EDX andl $65520, %edx //R[edx]←R[edx] and 65520,将z&0xFFF0送EDX addl %ecx, %edx //R[edx]←R[edx] + R[ecx],将z&0xFFF0+y*256送EDX subl %edx, %eax //R[eax]←R[eax]-R[edx],将x*k-(z&0xFFF0+y*256)送EAX 根据以上分析可知,第3行缺失部分为: 3 int v = 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为unsigned long long。 movl 12(%ebp), %eax //R[eax]←M[R[ebp]+12],将x送EAX movl 20(%ebp), %ecx //R[ecx]←M[R[ebp]+20],将yh送ECX imull %eax, %ecx //R[ecx]←R[ecx]*R[eax],将yh*x的低32位送ECX mull 16(%ebp) //R[edx]R[eax]←M[R[ebp]+16]*R[eax],将yl*x送EDX-EAX leal (%ecx, %edx), %edx // R[edx]←R[ecx]+R[edx],将yl*x的高32位与yh*x的低32位相加后送EDX movl 8(%ebp), %ecx //R[ecx]←M[R[ebp]+8],将d送ECX movl %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。 (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)汇编指令的注解说明如下: 1 movb 8(%ebp), %dl //R[dl]←M[R[ebp]+8],将x送DL 2 movl 12(%ebp), %eax //R[eax]←M[R[ebp]+12],将p送EAX 3 testl %eax, %eax //R[eax] and R[eax],判断p是否为0 4 je .L1 //若p为0,则转.L1执行 5 testb $0x80, %dl //R[dl] and 80H,判断x的第一位是否为0 6 je .L1 //若x>=0,则转.L1执行 7 addb %dl, (%eax) //M[R[eax]]←M[R[eax]]+R[dl],即*p+=x 8 .L1: 因为C语言if语句中的条件表达式可以对多个条件进行逻辑运算,而汇编代码中一条指令只能进行一种逻辑运算,并且在每条逻辑运算指令生成的标志都是存放在同一个EFLAGS寄存器中,所以,最好在一条逻辑指令后跟一条条件转移指令,把EFLAGS中标志用完,然后再执行另一次逻辑判断并根据条件进行转移的操作。 (2)按照书中图3.22给出的“if () goto …”语句形式写出汇编代码对应的C语言代码如下: 1 void comp(char x, int *p) 2 { 3 if (p!=0) 4 if (x<0) 5 *p += x; 6 } 13.参考答案: 1 int func(int x, int y) 2 { 3 int z = x*y ; 4 if ( x<=-100 ) { 5 if ( y>x ) 6 z = x+y ; 7 else 8 z = x-y ; 9 } else if ( x>=16 ) 10 z = x &y ; 11 return z; 12 } 14.参考答案: (1)每个入口参数都要按4字节边界对齐,因此,参数x、y和k入栈时都占4个字节。 1 movw 8(%ebp), %bx //R[bx]←M[R[ebp]+8],将x送BX 2 movw 12(%ebp), %si //R[si]←M[R[ebp]+12],将y送SI 3 movw 16(%ebp), %cx //R[cx]←M[R[ebp]+16],将k送CX 4 .L1: 5 movw %si, %dx //R[dx]←R[si],将y送DX 6 movw %dx, %ax //R[ax]←R[dx],将y送AX 7 sarw $15, %dx //R[dx]←R[dx]>>15,将y的符号扩展16位送DX 8 idiv %cx //R[dx]←R[dx-ax]÷R[cx]的余数,将y%k送DX //R[ax]←R[dx-ax]÷R[cx]的商,将y/k送AX 9 imulw %dx, %bx //R[bx]←R[bx]*R[dx],将x*(y%k) 送BX 10 decw %cx //R[cx]←R[cx]-1,将k-1 送CX 11 testw %cx, %cx //R[cx] and R[cx],得OF=CF=0,负数则SF=1,零则ZF=1 12 jle .L2 //若k小于等于0,则转.L2 13 cmpw %cx, %si //R[si] - R[cx],将y与k相减得到各标志 14 jg .L1 //若y大于k,则转.L1 15 .L2: 16 movswl %bx, %eax // R[eax]←R[bx],将x*(y%k) 送AX (2)被调用者保存寄存器有BX、SI,调用者保存寄存器有AX、CX和DX。 在该函数过程体前面的准备阶段,被调用者保存的寄存器EBX和ESI必须保存到栈中。 (3)因为执行第8行除法指令前必须先将被除数扩展为32位,而这里是带符号数除法,因此,采用算术右移以扩展16位符号,放在高16位的DX中,低16位在AX中。 15.参考答案: 1 int f1(unsigned x) 2 { 3 int y = 0 ; 4 while ( x!=0 ) { 5 y ^=x ; 6 x>>=1 ; 7 } 8 return y&0x1 ; 9 } 函数f1的功能返回:( x ^ x>>1 ^ x>>2 ^ ….) & 0x1,因此f1用于检测x的奇偶性,当x中有奇数个1,则返回为1,否则返回0。 16.参考答案: 函数sw只有一个入口参数x,根据汇编代码的第2~5行指令知,当x+3>7时转标号.L7处执行,否则,按照跳转表中的地址转移执行,x与跳转目标处标号的关系如下: x+3=0:.L7 x+3=1:.L2 x+3=2:.L2 x+3=3:.L3 x+3=4:.L4 x+3=5:.L5 x+3=6:.L7 x+3=7:.L6 由此可知,switch (x) 中省略的处理部分结构如下: case -2: case -1: …… // .L2标号处指令序列对应的语句 break; case 0: …… // .L3标号处指令序列对应的语句 break; case 1: ……. // .L4标号处指令序列对应的语句 break; case 2: …… // .L5标号处指令序列对应的语句 break; case 4: …… // .L6标号处指令序列对应的语句 break; default: …… // .L7标号处指令序列对应的语句 17.参考答案: 根据第2、3行指令可知,参数a是char型,参数p是指向short型变量的指针;根据第4、5行指令可知,参数b和c都是unsigned short型,根据第6行指令可知,test的返回参数类型为unsigned int。因此,test的原型为: unsigned int test(char a, unsigned short b, unsigned short c, short *p); 18.参考答案: 每次执行pushl指令后,R[esp]=R[esp]-4,因此,第2行指令执行后R[esp]=0xbc00001c。 (1)执行第3行指令后,R[ebp]=R[esp]=0xbc00001c。到第12条指令执行结束都没有改变EBP的内容,因而执行第10行指令后,EBP的内容还是为0xbc00001c。执行第13行指令后,EBP的内容恢复为进入函数funct时的值0xbc000030。 (2)执行第3行指令后,R[esp]=0xbc00001c。执行第4行指令后R[esp]= R[esp]-40=0xbc00001c-0x28=0xbbfffff4。因而执行第10行指令后,未跳转到scanf函数执行时,ESP中的内容为0xbbfffff4-4=0xbbfffff0;在从scanf函数返回后ESP中的内容为0xbbfffff4。执行第13行指令后,ESP的内容恢复为进入函数funct时的旧值,即R[esp]=0xbc000020。 (3)第5、6两行指令将scanf的第三个参数&y入栈,入栈的内容为R[ebp]-8=0xbc000014;第7、8两行指令将scanf的第二个参数&x入栈,入栈的内容为R[ebp]-4=0xbc000018。故x和y所在的地址分别为0xbc000018和0xbc000014。 ESP 从scanf返回的地址 0xbc00001c 0xbc000030 y=20 x=15 EBP 0xbc000018 0xbc000014 0xbc000010 0xbc00000c 0xbc000008 0xbc000004 0xbc000000 0xbbfffffc 0xbbfffff8 0xbbfffff4 0xbbfffff0 0xbc000014 0xbc000018 0x804c000 栈帧底部 (4)执行第10行指令后,funct栈帧的地址范围及其内容如下: 19.参考答案: 第1行汇编指令说明参数x存放在EBX中,根据第4行判断x=0则转.L2,否则继续执行第5~10行指令。根据第5、6、7行指令可知,入栈参数nx的计算公式为x>>1;根据第9、10、11行指令可知,返回值为(x&1)+rv。由此推断出C缺失部分如下: 1 int refunc(unsigned x) { 2 if ( x==0 ) 3 return 0 ; 4 unsigned nx = x>>1 ; 5 int rv = refunc(nx) ; 6 return (x & 0x1) + rv ; 7 } 该函数的功能为计算x的各个数位中1的个数。 20.参考答案: 在IA-32中,GCC为数据类型long double型变量分配12字节空间,实际上只占用10个字节。 数组 元素大小(B) 数组大小(B) 起始地址 元素i的地址 char A[10] 1 10 &A[0] &A[0]+i int B[100] 4 400 &B[0] &B[0]+4i short *C[5] 4 20 &C[0] &C[0]+4i short **D[6] 4 24 &D[0] &D[0]+4i long double E[10] 12 120 &E[0] &E[0]+12i long double *F[10] 4 40 &F[0] &F[0]+4i 21.参考答案: 表达式 类型 值 汇编代码 S short * AS leal (%edx), %eax S+i short * AS+2*i leal (%edx, %ecx, 2), %eax S[i] short M[AS+2*i] movw (%edx, %ecx, 2), %ax &S[10] short * AS+20 leal 20(%edx), %eax &S[i+2] short * AS+2*i+4 leal 4(%edx, %ecx, 2), %eax &S[i]-S int (AS+2*i-As)/2=i movl %ecx, %eax S[4*i+4] short M[AS+2*(4*i+4)] movw 8(%edx, %ecx, 8), %ax *(S+i-2) short M[AS+2*(i-2)] movw -4(%edx, %ecx, 2), %ax 22.参考答案: 根据汇编指令功能可以推断最终在EAX中返回的值为: M[a+28*i+4*j]+M[b+20*j+4*i],因为数组a和b都是int型,每个数组元素占4B,因此,M=5, N=7。 23.参考答案: 执行第11行指令后,a[i][j][k]的地址为a+4*(63*i+9*j+k),所以,可以推断出M=9,N=63/9=7。根据第12行指令,可知数组a的大小为4536字节,故L=4536/(4*L*M)=18。 24.参考答案: (1)常数M=76/4=19,存放在EDI中,变量j存放在ECX中。 (2)上述优化汇编代码对应的函数trans_matrix的C代码如下: 1 void trans_matrix(int a[M][M]) { 2 int i, j, t, *p; 3 int c=(M<<2); 3 for (i = 0; i < M; i++) { 4 p=&a[0][i]; 5 for (j = 0; j < M; j++) { 6 t=*p; 7 *p = a[i][j]; 8 a[i][j] = t; 9 p += c; 10 } 11 } 12 } 25.参考答案: (1)node所需存储空间需要4+(4+4)+4=16字节。成员p、s.x、s.y和next的偏移地址分别为0、4、8和12。 (2)np_init中缺失的表达式如下: void np_init(struct node *np) { np->s.x = np->s.y ; np->p = &(np->s.x) ; np->next= np ; } 26.参考答案: 表达式EXPR TYPE类型 汇编指令序列 uptr->s1.x int movl (%eax), %eax movl %eax, (%edx) uptr->s1.y short movw 4(%eax), %ax movw %ax, (%edx) &uptr->s1.z short * leal 6(%eax), %eax movw %eax, (%edx) uptr->s2.a short * movl %eax, (%edx) uptr->s2.a[uptr->s2.b] short movl 4(%eax), %ecx movl (%eax, %ecx, 2), %eax movl %eax, (%edx) *uptr->s2.p char movl 8(%eax), %eax movb (%eax), %al movb %al, (%edx) 27.参考答案: (1)S1: s c i d 0 2 4 8 总共12字节,按4字节边界对齐 (2)S2: i s c d 0 4 6 7 总共8字节,按4字节边界对齐 (3)S3: c s i d 0 2 4 8 总共12字节,按4字节边界对齐 (4)S4: s c 0 6 总共8字节,按2字节边界对齐 (5)S5: c s i d e 0 4 8 12 16 总共24字节,按4字节边界对齐(Linux下double型按4字节对齐) (6)S6: c s d 0 36 40 总共44字节,按4字节边界对齐 28.参考答案: Windows平台要求不同的基本类型按照其数据长度进行对齐。每个成员的偏移量如下: c d i s p l g v 0 8 16 20 24 28 32 40 结构总大小为48字节,因为其中的d和g必须是按8字节边界对齐,所以,必须在末尾再加上4个字节,即44+4=48字节。变量长度按照从大到小顺序排列,可以使得结构所占空间最小,因此调整顺序后的结构定义如下: struct { double d; long long g; int i; char *p; long l; void *v; short s; char c; } test; d g i p l v s c 0 8 16 20 24 28 32 34 结构总大小为34+6=40字节。 29.参考答案: (1)执行第7行和第10行指令后栈中的信息存放情况如下图所示。其中gets函数的入口参数为buf数组首 地址,应等于getline函数的栈帧底部指针EBP的内容减0x14,而getline函数的栈帧底部指针EBP的内容应等于执行完getline中第2行指令(push %ebp)后ESP的内容,此时,R[esp]= =0xbffc07f0-4=0xbffc07ec,故buf数组首地址为R[ebp]-0x14= R[esp]-0x14=0xbffc07ec-0x14=0xbffc07d8。 a) 执行第7行后的栈 ESP EBP EBP在P中旧值 08 04 85 c8 返回P的地址 bf fc 08 00 00 00 00 08 00 00 00 10 00 00 00 05 被调用者保存寄存器在P中的旧值 buf[7]~ buf[4] buf[3]~ buf[0] b) 执行第10行后的栈 ESP EBP EBP在P中旧值 08 41 39 38 返回P的地址 37 36 35 34 33 32 31 30 46 45 44 43 42 41 39 38 被调用者保存寄存器在P中的旧值 buf[7]~ buf[4] buf[3]~ buf[0] 33 32 31 30 37 36 35 34 gets入口参数 bf fc 07 d8 (2)当执行到getline的ret指令时,假如程序不发生段错误,则正确的返回地址应该是0x80485c8,发生段错误是因为执行getline的ret指令时得到的返回地址为0x8413938,这个地址所在存储段可能是不可执行的数据段,因而发生了段错误(segmentation fault)。 (3)执行完第10行汇编指令后,被调用者保存寄存器EBX、ESI和EDI在P中的内容已被破坏,同时还破坏了EBP在P中的内容。 (4)getline的C代码中malloc函数的参数应该为strlen(buf)+1,此外,应该检查malloc函数的返回值是否为NULL。 30.参考答案: x86-64过程调用时参数传递是通过通用寄存器进行的,前三个参数所用寄存器顺序为RDI、RSI、RDX。 abc的4种合理的函数原型为: ① viod abc(int c, long *a, int *b); ② viod abc(unsigned c, long *a, int *b); ③ viod abc(long c, long *a, int *b); ④ viod abc(unsigned long c, long *a, int *b); 根据第3、4行指令可知,参数b肯定指向一个32位带符号整数类型;根据第5行指令可知,参数a指向64位带符号整数类型;而参数c可以是32位,也可以是64位,因为*b为32位,所以取RDI中的低32位R[edi](截断为32位),再和*b相加。同时,参数c可以是带符号整数类型,也可以是无符号整数类型,因为第2行加法指令addl的执行结果对于带符号整数和无符号整数都一样。 31.参考答案: (1)汇编指令注释如下: 1 movl 8(%ebp), %edx //R[edx]←M[R[ebp]+8],将x送EDX 2 movl 12(%ebp), %ecx //R[ecx]←M[R[ebp]+12],将k送ECX 3 movl $255, %esi //R[esi]←255,将255送ESI 4 movl $-2147483648, %edi //R[edi]←-2147483648,将0x80000000送EDI 5 .L3: 6 movl %edi, %eax //R[eax]←R[edi],将i送EAX 7 andl %edx, %eax //R[eax]←R[eax] and R[edx],将i and x送EAX 8 xorl %eax, %esi //R[esi]←R[esi] xor R[eax],将val xor (i and x)送ESI 9 movl %ecx, %ebx //R[ebx]←R[ecx],将k送ECX 10 shrl %bl, %edi //R[edi]←R[edi] >> R[bl],将i逻辑右移k位送EDI 11 testl %edi, %edi 12 jne .L3 //若R[edi]≠0,则转.L3 13 movl %esi, %eax //R[eax]←R[esi] (2)x和k分别存放在EDX和ECX中。局部变量val和i分别存放在ESI和EDI中。 (3)局部变量val和i的初始值分别是255和-2147483648。 (4)循环终止条件为i等于0。循环控制变量i每次循环被逻辑右移k位。 (5)C代码中缺失部分填空如下,注意:对无符号整数进行的是逻辑右移。 1 int lproc(int x, int k) 2 { 3 int val = 255 ; 4 int i; 5 for (i= -2147483648 ; i != 0 ; i= (unsigned) i >> k ) { 6 val ^= (i & x) ; 7 } 8 return val; 9 } 32.参考答案: 从第5行指令可知,i在EAX中;从第6行指令可知,sptr在ECX中。由第7行指令可知,i*28在EBX中。由第8、9和10行指令可猜出,x的每个数组元素占28B,并且xptr->idx的地址为sptr+i*28+4,故在line_struct中的第一个分量为idx,因而后面的24B为6个数组元素a[0]~a[5],类型与val变量的类型相同,即unsigned int。 line_struct结构类型的定义如下: typedef struct { int idx; unsigned a[6]; } line_struct; 由第11、12行指令可知,x数组所占空间为0xc8-4=200-4=196B,所以LEN=196/28=7。 33.参考答案: (1)n1.ptr、n1.data1、n2.data2、n2.next的偏移量分别是0、4、0和4。 (2)node类型总大小占8字节。 (3)chain_proc的C代码中缺失的表达式如下: uptr-> n2.next ->n1.data1 = *(uptr->n2. next->n1. ptr ) – uptr->n2. data2 ; 34.参考答案: (1)函数trace的入口参数tptr通过RDI寄存器传递。 (2)函数trace完整的C语言代码如下: long trace( tree_ptr tptr) { long ret_val=0; tree_ptr p=tptr; while (p!=0) { ret_val=p->val; p=p->left; } return ret_val; } (3)函数trace的功能是:返回二叉树中最左边叶子节点中的值val。展开阅读全文

咨信网声明:本文档由用户上传并分享,仅供学习交流、研究之用,未经授权,严禁复制、发行、汇编、翻译或网络传播等,侵权必究。
咨信网小贴示:
1、浏览或下载可查看了解,请点击【咨信网告知】。
2、下载文件中如有侵权或不适当内容,将立即纠正。
3、如果因为网速或其他原因下载失败请重新下载,重复下载[60天内]不扣币。
4、开具发票登录电脑端申请,请点击【索取发票】。
咨信网客服组:【微信客服】
1、浏览或下载可查看了解,请点击【咨信网告知】。
2、下载文件中如有侵权或不适当内容,将立即纠正。
3、如果因为网速或其他原因下载失败请重新下载,重复下载[60天内]不扣币。
4、开具发票登录电脑端申请,请点击【索取发票】。
咨信网客服组:【微信客服】


计算机系统第三章答案剖析.doc
















自信AI助手














微信客服
客服QQ
发送邮件
意见反馈



链接地址:https://www.zixin.com.cn/doc/10820730.html