好文档 - 专业文书写作范文服务资料分享网站

计算机系统第三章答案

天下 分享 时间: 加入收藏 我要投稿 点赞

&S[i+2] &S[i]-S S[4*i+4] *(S+i-2) short * int short short AS+2*i+4 (AS+2*i-As)/2=i M[AS+2*(4*i+4)] M[AS+2*(i-2)] leal 4(íx, ìx, 2), êx movl ìx, êx movw 8(íx, ìx, 8), %ax movw -4(íx, ìx, 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、、和next的偏移地址分别为0、4、8和12。 (2)np_init中缺失的表达式如下:

void np_init(struct node *np) {

np-> = np-> ;

np->p = &(np-> ; np->next= np ; }

26.参考答案: 表达式EXPR uptr-> uptr-> &uptr-> uptr-> uptr->[uptr->] TYPE类型 int short short * short * short 汇编指令序列 movl (êx), êx movl êx, (íx) movw 4(êx), %ax movw %ax, (íx) leal 6(êx), êx movw êx, (íx) movl êx, (íx) movl 4(êx), ìx movl (êx, ìx, 2), êx *uptr-> char movl êx, (íx) movl 8(êx), êx movb (êx), %al movb %al, (íx)

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 ?p)后ESP的内容,此时,R[esp]= =0xbffc07f0-4=0xbffc07ec,故buf数组首地址为R[ebp]-0x14= R[esp]-0x14=0xbffc07ec-0x14=0xbffc07d8。

EBP

08 04 85 c8 返回P的地址 bf fc 08 00 EBP在P中旧值 00 00 00 08 00 00 00 10 00 00 00 05 被调用者保

存寄存器在P中的旧值 buf[7]~ buf[4] buf[3]~ buf[0]

EBP

08 41 39 38 返回P的地址

37 36 35 34 EBP在P中旧值 被调用者保46 45 44 43 存寄存器在42 41 39 38 P中的旧值 37 36 35 34 buf[7]~ 33 32 31 30 buf[4]buf[3]~ buf[0] 33 32 31 30 ESP

a) 执行第7行后的栈

ESP

bf fc 07 d8 gets入口参数

b) 执行第10行后的栈

(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(?p), íx 3: 6 movl íi, êx 3 3

13 movl %esi, êx 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。

计算机系统第三章答案

&S[i+2]&S[i]-SS[4*i+4]*(S+i-2)short*intshortshortAS+2*i+4(AS+2*i-As)/2=iM[AS+2*(4*i+4)]M[AS+2*(i-2)]leal4(íx,ìx,2),êxmovlìx,êxmovw8(íx,ìx,8),%axmovw-4(íx,ìx,2
推荐度:
点击下载文档文档为doc格式
6jarw3vvbz507xn0uyq64mg6283nif00q1p
领取福利

微信扫码领取福利

微信扫码分享