3.67

【答案】

A.

%rsp + 24 z             
%rsp + 16 &z           
%rsp + 8 y            
%rsp     x            

B. 由汇编代码eval的第8行以及process的第2行可以看出传递了%rdi的值,为%rsp + 64

C. 通过%rsp + offset(偏移量)

D. 由汇编代码process可以看出通过传递给%rsp + 64 ,并从该地址开始将结构r的字段存储在栈上

E.以第一列的地址为起始地址向上存

变量是按顺序分配栈的,由此可以写出变量的位置(要注意process中的%rsp与eval中的%rsp不是同一个,比如在eval中%rsp + 8为y,在process中的第7行%rsp + 8传给%rcx,传送的值就不是y,而是把新的%rsp+8的值传给%rcx,所以应该看源代码变量名是按顺序存在栈中,确定变量名的位置,对应值也应看源代码)

栈中位置 变量名 储存值
%rsp + 80 r.q z
%rsp + 72 r.u[1] x
%rsp + 64 r.u[0] y
%rsp + 24 参数z z
%rsp + 16 s.p &z
%rsp + 8 s.a[1] y
%rsp  s.a[0] x

通过eval汇编代码的第10~12行可以看出,通过%rsp + offset 的方式访问r的元素

F. 无论是传参还是返回,结构值都是存储在栈上,而不是寄存器中。

3.68

【答案】

A=9
B=5

【解释】

根据结构体的内存对齐原则,由汇编代码第2行int相对起始地址偏移8个字节,可以得知 array数组的实际大小的字节一定大于4(否则int起始地址为4),且小于等于8,所以4<B<=8;int占4字节,可知short数组起始地址的偏移量为12,又long起始地址偏移32,且short数组占用大小20(32-12)个字节,所以short数组实际大小占用一定大于12(原理同上),且小于等于20,所以6<A<=10;由汇编第四行知180<=A*B*4<=184,综合上面的推断发现只有A=9,B=5满足。

3.69

【答案】

A.CNT = 7
B.typedef struct {long idx;long x[4];} a_struct

【解释】

A. 由汇编代码第2行0x120(288)知first与结构体数组a共占用288字节,由第6行知结构体数组按8字节对齐,所以为了对齐,first占用8字节,则结构体数组a占用280字节,由由第3~4行(bp+40i)知一个结构体a大小为40字节,所以INT = 280/40 = 7.

B.

ap->x[ap->idx] = n;
#其实可以就是bp->a[i].x[bp->a[i].idx]
mov    %rcx, 0x10(%rax, %rdx, 8)
#所以bp->a[i].x[bp->a[i].idx]地址的计算公式为 16 + (&bp + 40i) + 8*(8 + bp + 40i)
#不妨把i设为0,方便我们观察
#所以计算地址变为 16 + &bp + 8*(8 + bp)
# 因为first占用8个字节,16 说明a的第一个参量一定是数idx ,且大小为8个字节,则(8 + bp)就表示idx,8 * idx 说明数组x的一个元素大小为8字节,结构体a总共占40个字节,idx占8,则数组x占32,
所以元素个数 = 32 / 8 = 4;

3.70

【答案】

A. e1.p     0e1.y     8e2.x     0e2.next  8
B. 16
C. void proc(union ele *up){up->e2.x = *(up->e2.next->e1.p) - up->e2.next->e1.y;}

【解释】

C.

1   proc:
2       movq    8(%rdi), %rax#因为这是个联合体,所以8 + rdi有两种可能,一个是up->e1.y,一个是up->e2.next;
3       movq    (%rax), %rdx#此处(%rax)说明%rax储存的为地址,则可以确定上面%rax为up->e2.next;此时%rdx有两种可能:up->e2.next->e1.p, up->e2.next->e2.x;
4       movq    (%rdx), %rdx#此处(%rdx)说明存储的为地址,则推出上面为up->e2.next->e1.p
5       subq    8(%rax), %rdx#上面分析知%rax为up->e2.next,减去8(%rax)说明8 + %rax 为数,则此时读取的是up->e2.next->e1.y
6       movq    %rdx, (%rdi)#%rdx存储的是一个数,知(%rdi)为up->x
7       ret

3.71

【答案】

1 #include <stdio.h>
2 #define N 100
3 void good_echo(void)
4 {
5    char str[N];
6    while(1)
7    {
8        char* p = fgets(str,N,stdin);
9        if(p==NULL)
10       {
11           break;
12       }
13       printf("%s",p);
14   }
15    return 0;
16 }

【解释】

首先fgets的作用是将字符串读入数组,并返回该数组的首地址,所以我们用一个字符型指针指向返回值,当其不是空指针时便打印出内容,fgets不断读取文件内容一直到遇到换行或者达到最大长度时结束,下一次循环在上次位置继续读取,当读取到文件末尾时,返回一个空指针,从而结束整个循环。

3.72

【答案】

A.

当n为奇数时:s2 = s1 - (8 * n + 24)

当n为偶数时:s2 = s1 - (8 * n + 16)

B. p = 将s2向上舍入为16的倍数

C.

e1 s1
max=24 s1%16==0 n%2==1(奇数)
min=1 s1%16==1 n%2==0(偶数)

D.s2的计算方式会保留s1的偏移量为最接近16的倍数,p以16的倍数对齐。

【解释】

这道题可以仔细看一下练习题3.49

A.第五行指令leaq计算值为8n + 30,-16的位表示为 10000,所以与-16与就相当于把8n + 30向下舍入为16的倍数,当n为奇数时把8n + 30看作(8n + 8) + 16 + 6,所以向下舍入为16的倍数就是(8n + 8) + 16,即8n + 24,偶数时看作8n + 16 + 14,向下舍入为16的倍数就是8n + 16 ,然后用s1减去这个值就得到s2。

B. 第8行的leaq指令为%rsp + 15,然后下一行与-16与,其实就相当于首先给%rsp一个偏移量,然后再舍入为16的倍数,产生的效果就是向上舍入为16的倍数(这个地方不懂可以仔细看一下p73页除以2的幂向上舍入那里)

C. 结合图3-44方便理解,首先从s1到s2的空间大小上面已经知道,n为奇数时:(8 * n + 24)。n为偶数时:  (8 * n + 16),减去数组p占用的空间大小8n,剩下的空间大小(24或16)就是e1 + e2一共占用的空间大小

所以要使e1最小首先要使e1 + e2的和最小,那么n就是偶数,则e1 + e2 的大小为16,和的值确定了要使e1最小则必须使e2的值最大,e2的大小又等于p - s2,由第二问知p等于s2向上舍入成16的倍数,所以s2的地址应该是16的倍数再加1,因为向上舍入为16的倍数,就会在s2的地址上加上15得到p的地址(比如s2=17,那么p = 32, e2 = 15),则e2的大小就是15,e1 = 16 -15 = 1。

同理可以得到e1最大为24。

D.由前面的分析可以得答案。

3.73

【答案】

1 find_range:
2     vxorps %xmm1, %xmm1, %xmm1
3     vucomiss      %xmm1, %xmm0
4     jp .L1
5     ja .L2
6     jb .L3
7     je .L4
8   .L1:
9     movl $3, %eax
10    jmp  .End
11  .L2:
12    movl $2, %eax
13    jmp  .End
14  .L3:
15    movl $0, %eax
16    jmp  .End
17  .L4:
18    movl $1, %eax
19  .End:
20    rep; ret

【解释】

这里采用的方法是编写完整函数,放入一个独立的汇编代码文件,并且让汇编器和链接器将其与c语言书写的代码合并。

原来得指令生成了两次浮点常数,以及生成OTHER=3的过程,可以去掉,只需要compare 0:x,使用条件分支指令实现。

3.74

【答案】

1      vxorps    %xmm1, %xmm1, %xmm1    # %xmm1清零
2      movq      $1, %rax               # result = 1
3      movq      $2, %r8
4      movq      $0, %r9
5      movq      $3, %r10
6      vucomiss  %xmm1, %xmm0           # compare x:0
7      cmovaq    %r8, %rax"             # if > ,  result = 2
8      cmovbq    %r9, %rax              # if < ,  result = 0
9      cmovpq    %r10, %rax             # if NAN, result = 3

【解释】

要求使用条件传送,所以与上一题相比只不过把条件跳转,改成了条件传送。

3.75

【答案】

A.

第几个参数 实部 虚部
1 %xmm0 %xmm1
2 %xmm2 %xmm3
3 %xmm4 %xmm5
n %xmm(2n-2) %xmm(2n-1)

B.将返回值的实部存在%xmm0,虚部存放在%xmm1。

【解释】

A. 首先看c_imag,汇编代码第2行将%xmm1传递给%xmm0,然后返回%xmm0,说明x的虚部存放在%xmm1,再看c_real第二行直接返回,因为%xmm0为默认的保存返回值的寄存器,所以%xmm0存放的为实部。观察c_sub,因为我们知道了%xmm0为实部,所以可知%xmm2也为实部,就说明第二个参数的实部存放在%xmm2,同理可知第二个人参数的虚部存放在%xmm3,以此类推第n个参数的实部就存放在%xmm(2n-2),虚部存放在%xmm(2n-1)。

B.由c_sub的汇编代码知道%xmm0用于存放返回值的实部,%xmm1用于存放返回值的虚部。

【仅供参考】csapp第三章课后习题答案(欢迎批评指正)相关推荐

  1. 《计算机网络技术》第三章课后习题答案(全)

    <计算机网络技术>第三章课后习题答案(全) 1.网络协议包括的三要素是什么? 答: 语法.语义和时序关系. 2.在计算机网络中使用分层的思想有哪些好处? 答: (1)各层次之间可相互独立: ...

  2. 郑莉java课后答案,Java语言程序设计(郑莉)第三章课后习题答案

    <Java语言程序设计(郑莉)第三章课后习题答案>由会员分享,可在线阅读,更多相关<Java语言程序设计(郑莉)第三章课后习题答案(10页珍藏版)>请在人人文库网上搜索. 1. ...

  3. 工程伦理(2021春)第三章课后习题答案

    工程伦理(2021春)第一章课后习题答案 工程伦理(2021春)第二章课后习题答案 工程伦理(2021春)第四章课后习题答案 工程伦理(2021春)第五章课后习题答案 工程伦理(2021春)第六章课后 ...

  4. 计算机网络原理(谢希仁第八版)第三章课后习题答案

    第三章 1.数据链路(即逻辑链路)与链路(即物理链路)有何区别? "电路接通了"与"数据链路接通了"的区别何在? 答:数据链路与链路的区别在于数据链路出链路外, ...

  5. 《Python语言程序设计》王恺 机械工业出版社 第三章课后习题答案

    ​​第三章   函数 3.7 课后习题 (1)在Python语言中,使用函数分为两个步骤:定义函数和调用函数 (2)在Python语言中,函数定义需要使用def关键字 (3)形参是在定义函数时函数后面 ...

  6. 【最详细】数据结构(C语言版 第2版)第三章课后习题答案 严蔚敏 等 编著

    所有章节答案合集-->传送门 1.选择题 ( 1)若让元素 1, 2, 3, 4, 5 依次进栈,则出栈次序不可能出现在()种情况. A. 5, 4, 3, 2, 1 B. 2, 1, 5, 4 ...

  7. 数据库系统概论(第五版) 王珊 第三章课后习题答案

    1 .试述 sQL 语言的特点. 答: (l)综合统一. sQL 语言集数据定义语言 DDL .数据操纵语言 DML .数据控制语言 DCL 的功能于一体. (2)高度非过程化.用 sQL 语言进行数 ...

  8. 计算机网络-自顶向下方法 第三章课后习题答案(第七版)

    复习题 R1. a) 就叫这个协议为简单传输协议STP(Simple Transport Protocol).在发送方,STP从发送进程接收不超过1196字节的数据块.目标主机地址和目标端口号.STP ...

  9. 微机原理与接口技术[第三版]——第三章课后习题答案

    10.指出寻址方式 (1)MOV AX,BX                           寄存器寻址 (2)MOV DL,20H                         立即寻址 (3 ...

最新文章

  1. 推荐65个以自然风光为背景的UI设计
  2. pyhon制作word、excel、ppt转pdf转换器大作战
  3. python rsa加密二进制文件_用Python中的RSA加密文件
  4. MATLAB之基本语法之常用命令
  5. 思杰彻底简化浏览器应用的安全交付
  6. ssm整合(crm案例)
  7. 谈谈坚持写博客的感悟
  8. 关于内网打印机的研究-利用PRET对惠普打印机进行渗透
  9. oracle 数据库 有坏快,ORACLE数据库坏块的处理 (处理无对象坏快的方法)
  10. 查找代码文件中的非 ASCII 字符
  11. 低代码时代的团队分工有哪些?
  12. Spring Boot 项目鉴权的 4 种方式
  13. 单片机c语言篮球比分_单片机课程设计篮球计时计分器正文1
  14. mmwave studio使用
  15. 【pytest】(详解)@pytest.mark.parametrize: 参数化测试函数
  16. ADS滤波器设计向导工具一
  17. cannot find a java se sdk installed at path_SDK管理器找不到Java
  18. 基于SSM网上商城购物系统的设计与实现
  19. 智慧警务——大数据时代的警务模式
  20. 生产现场车间数字化可视化管理系统软件

热门文章

  1. 外部设备如何连接到虚拟机中
  2. 固态U盘量产:群联PS3111主控开卡量产工具使用教程
  3. 数据合规可信计划暨国内首个数据合规标准发布!易观作为标准起草单位应邀参加
  4. 5个小故事,告诉你运营中的那些套路有多深
  5. RAW(裸) 与 QCOW2(写时复制) 的区别
  6. AFL(American Fuzzy Lop)源码详细解读(3)
  7. AFL(American Fuzzy Lop)源码详细解读(2)
  8. 智慧医疗健康监护,从慢性疾病到术后护理
  9. export与export default的区别
  10. 零基础Python数据分析实战:豆瓣人的电影口味重吗?