2017-2018-1 20155312 《信息安全系统设计基础》第七周学习总结
教材学习内容总结
第七周学习了教材第4章的内容,包括Y86-64指令集中的汇编指令对应的字节序列,指令与序列之间的转换,硬件控制语言HCL,Y86-64顺序处理的6个阶段,每个指令对应的处理情况和SEQ硬件结构,SEQ的实现。
教材学习中的问题和解决过程
- 问题1:教材第246页中指出Y86-64的movq指令中两个内存传送指令中的内存引用方式是简单的基址和偏移量形式。不支持第二变址寄存器和任何寄存器值的伸缩。这里的“第二变址寄存器和任何寄存器值的伸缩”是什么意思呢?
- 问题1解决方案:首先我搜索了百度百科和维基百科“第二变址寄存器”的概念,结果是一无所获,我又返回书中第三章入手,想再复习一遍x86-64的所有寻址方法,从其中的变址寻址中找到关于“第二变址寄存器和寄存器值伸缩”的答案,通过阅读书第121页,我推测,变址寻址方式应该可以按照有无比例因子s分为两类,这里Y86-64应该是不支持较复杂的带有s的第二类变址寻址:M[R[ri]·s]、M[Imm+R[ri]·s]、M[R[rb]+R[ri]·s]、M[Imm+R[rb]+R[ri]·s]。
- 问题2:教材第248页练习题4.2中的C、E两组指令的字节序列中都有“f0”,在246页Y86-64的指令集中找不到f0对应的指令,那这里的f0代表什么含义呢?
- 问题2解决方案:通过查看第四章最后练习题的答案,可以发现C段指令序列如下:
0x300: mrmovq $7(%rsp),%rbp
ox30a: nop
ox30b:.byte 0xf0 # Invalid instruction code
ox30c: popq %rcx
题目的解释为“f0”为非法指令指示字节,所以合乎我们的推测,凡是指令起始字节不是以“0-B”中的任意一个,那么这条指令就是一个非法指令,不管是“f0”还是别的什么。通过题目中的ox30c: popq %rcx我们知道,出现非法字节后,只影响以它起始的一个字节,从下一个字节开始可以照常将字节序列翻译为对应的Y86-64指令。
让我们再观察一下课后答案对E段指令序列的解释“pushq指令中第二个字节非法的代码”:
0x500: xorq %rsi,%rdx
0x502:.byte 0xa0 # pushq instruction
code
0x503:.byte 0xf0 # Invalid register
观察上述命令我们比较容易理解,因为pushq rA 指令对应的字节应该是 A0 rAf,其中rA寄存器是不可为空的,但上题中将其置为“f0”代表的是:rA——无寄存器,rB——%rax。所以这里没有一个完整的pushq rA指令,原因在于f0是无效寄存器。
出现了上题中的非法指令,Y86-64的状态码Stat修改为INS。
- 问题3:如何搭建Y86-64的环境?
- 问题3解决方案:参考了狄惟佳的博客,我的操作过程如下:
- 命令行输入“sudo apt-get install bison flex”
- “sudo apt-get install tcl8.5-dev tk8.5-dev tcl8.5 tk8.5”
- 用虚拟机的浏览器打开网址“csapp.cs.cmu.edu/public/sim.tar ” 下载sim.tar到“/home/下载”目录下
- 在当前/home目录下进入“/home/下载”,解包文件sim.tar:“tar -xf sim.tar”
- 复制sim文件夹到指定位置:“cp -r /home/zjy/下载/sim ……”(如果上一步中用 “-C 路径”指定了解压后的路径,就不需要这步复制操作了)
- 进入sim文件夹,修改“Makefile”中的TKLIBS=-L/usr/lib -ltk8.5 -ltcl8.5和TKINC=-I/usr/include/tcl8.5这两行
- 保存修改后,运行“make”指令
- 进入“y86-code”文件夹,通过刚才的make指令,由.ys文件生成了很多.yo文件
- 输入“make asumi.yo”,系统显示“make: 'asumi.yo' is up to date.”
- 输入“make clean”,系统显示“rm -f *.o *.yis *~ *.yo *.pipe *.seq *.seq+ core”
- 输入“make asumi.yo”,系统显示“../misc/yas asumi.ys”
- 输入“cat asumi.yo”查看asumi.yo文件
- 问题4:为什么教材251页中图4-6的代码start++和count++翻译成汇编指令后,start要加8呢?long类型变量占四个字节,那如果start自增的目的是访问下一个元素,为什么start不是加4呢?
- 问题解决方案:书中245页说明了Y86-64只包含8字节的整数操作,只有8字节数据,所以我推测不管是什么类型的数据,都要留8字节的没存空间,因此start自增是加8。
- 问题5:教材252页中的array数组在定义时其四个成员为0x000d000d000d,0x00c000c000c0……,为什么253页中说明它们的值为0x000b000b000b000b,0x00c000c000c000c0……呢?如果每个值不足8字节,应该在最前面补零,变成0x00000d000d000d,0x0000c000c000c0……
- 问题5解决方案:通过查看教材254页中的机器码,可以发现实际计算机翻译的array数组是这样的:
0x018:0d000d000d000000
0x020:c000c000c0000000
……
我们知道,它是按照小端方式存储的,所以将其转化为真值后,是0x00000d000d000d,0x0000c000c000c0……与我们按照正常方法计算的结果一致。
- 问题6:教材279页中为什么word srcA = {icode in {IRRMOVY …… (这里为什么没有IMRNOVQ)}}?
- 问题6解决方案:虽然IMRNOVQ中涉及到rA,但是它不在议码段第一行,应该作为目标寄存器而不是源寄存器。
代码调试中的问题和解决过程
- 问题1:教材255页练习题4.4中,为什么用
andq %rsi,%rsi
je return
来表示代码if(count<=0) return 0;呢?je 是等于0时跳转,与小于等于不符,为什么不用subq + jle指令来描述代码呢?
- 问题1解决方案:通过阅读代码,可以发现,这个迭代求和函数每迭代一次会将count的值-1,所以count代表的应该是迭代次数,一旦当其减小到0时就返回0,所以如果是从完成程序的目的出发,这里判断count=0还是count<=0的效果是一样的。
代码托管
(运行statistics.sh脚本时出现了问题,与实际情况不符)
上周考试错题总结
假设下面位串是基于IEEE格式的5位浮点表示,一个符号位,2个阶码位,两个小数位。下面正确的是(AD)
A .
3.5的表示是[01011]
B .
-1.0的表示[01111]
C .
0.5的表示是[00011]
D .
1.5的表示是[00110]
有关三位数x,y的乘积x*y截断为四位,下面说法正确的是(BD)
A .
无符号的[100]*[101]结果为4
B .
无符号的[100]*[101]结果为-4
C .
有符号的[100]*[101]结果为-4
D .
有符号的[100]*[101]结果为4
我们用一个十六进制的数表示长度w=4的位模式,把数字解释为补码,关于其加法逆元的论述正确的是(ABDE)
A .
0x8的加法逆元是-8
B .
0x8的加法逆元是0x8
C .
0x8的加法逆元是8
D .
0xD的加法逆元是3
E .
0xD的加法逆元是0x3
我们用一个十六进制的数表示长度w=4的位模式,对于数字的无符号加法逆元的位的表示正确的是(AC)
A .
0x8的无符号加法逆元是0x8
B .
0xD的无符号加法逆元是0xD
C .
0xF的无符号加法逆元是0x1
D .
0xF的无符号加法逆元是
0<=x,y<2^w, 则(F)
A .
x+y的最大值是2^w
B .
x+y的最大值是2^w-1
C .
x+y的最大值是2^w-2
D .
x+y的最大值是2^(w+1)
E .
x+y的最大值是2^(w+1)-1
F .
x+y的最大值是2^(w+1)-2
B2T([1100])= (B)
A .
12
B .
-4
C .
3
D .
以上都不对
int x; x的二进制为[10010101], x>>4的值为(C)
A .
[10010101]
B .
[00001001]
C .
[11111001]
D .
[01010000]
下面和代码可移植性相关的C语言属性有(ABC)
A .
#define
B .
typedef
C .
sizeof()
D .
union
根据c89国际标准编译程序prog.c,下面正确的是(BC)
A .
gcc prog.c
B .
gcc -ansi prog.c
C .
gcc -std=c89 prog.c
D .
gcc -std=gnull prog.c
结对及互评
点评模板:
- 博客中值得学习的或问题:
- xxx
- xxx
- ...
- 代码中值得学习的或问题:
- xxx
- xxx
- ...
- 其他
本周结对学习情况
- 20155325
- 结对照片
- 结对学习内容
- 第四章学习
- 第二次实验
其他(感悟、思考等,可选)
这周学习第四章很认真,做了看过的每一个课后题。想要看完这章可能还需要一定时间,但我会尽量保证看过后的知识自己能够掌握。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 3/7 | 22/60 | |
第四周 | 300/1500 | 2/10 | 20/90 | |
第五周 | 300/1800 | 1/12 | 18/90 | |
第六周 | 300/2100 | 2/13 | 20/90 | |
第七周 | 0/2400 | 2/15 | 25/90 |
尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。
-
计划学习时间:XX小时
-
实际学习时间:XX小时
-
改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)