20145219 《信息安全系统设计基础》第06周学习总结
20145219 《信息安全系统设计基础》第06周学习总结
教材学习内容总结
实验楼实验
-
构建YIS环境
使用如下命令:
cd ~/Code/shiyanlou_cs413 wget http://labfile.oss.aliyuncs.com/courses/413/sim.tar tar -xvf sim.tar cd sim sudo apt-get install tk sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so make
-
YIS测试
进入
y86-code
,查看目录下内容(ls命令),只有.ys
文件
用
make all
命令(可以汇编运行所有代码结果)编译后,查看目录下内容,看到已经有编译后的.yo
文件
-
测试教材p239代码
进入测试代码,教材p239代码为
asuml.ys
,通过make asuml.yo
命令进行汇编,asuml.yo
就是汇编后的结果(见教材p240)。执行cat asuml.yo
命令可以将其显示在屏幕上。
-
虚拟机中安装Y86模拟器
安装成功,具体步骤参考博客链接http://www.cnblogs.com/hrhguanli/p/4594724.html
实现测试代码的结果与在实验楼中实现的相同
自我练习输入了p251下方右侧的代码,结果如下:
Y86指令集体系结构
-
Y86:包括定义各种状态元素、指令集和它们的编码、一组编程规范和异常事件处理。
-
程序员可见状态
1、Y86程序中每条指令都会读取或修改处理器状态的某些部分。
2、可以访问和修改程序寄存器、条件码、程序计数器和存储器,状态码指明程序是否运行正常。
- 8个程序寄存器:%eax、%ecx、%edx、%ebx、%esi、%edi、%esp、%ebp。每个程序寄存器存储一个字。%esp被入栈、出栈、调用和返回指令作为栈指针。
- 有3个一位的条件码:ZF、SF、OF,他们保存最近的算术或逻辑指令所造成影响的有关信息。
- 程序计数器(PC)存放当前正在执行的地址。
- 存储器:一个很大的字节数组,保存着程序和数据。
-
Y86指令
1、只包括四字节整数操作。
2、指令编码长度从1个字节到6个字节不等,一条指令含有一个单字节的指令指示符,可能含有一个单字节的寄存器指示符,还可能含有一个四字节的常数字。
字段fn指明是某个整数操作(OPL)、数据移动条件(cmovXX)或是分支条件(jXX)。
所有数值都用十六进制表示:
3、IA32的movl指令分成了4个不同的指令:irmovl、rrmovl、mrmovl和rmmovl。分别显示地指明源和目的的格式:
源操作数:立即数i、寄存器r、存储器m 目的操作数:寄存器r、存储器m
注意:
(1)两个存储器传送指令中的存储器引用方式是简单的基址和偏移量形式。 (2)在地址计算中,不支持第二变址寄存器和任何寄存器值的伸缩。 (3)不允许从一个存储器地址直接传送到另一个存储器地址。也不允许将立即数传送到存储器。
4、4个整数操作指令:addl、subl、andl、xorl
5、7个跳转指令(jXX):jmp、jle、jl、je、jne、jge、jg
6、6个条件传送指令(cmovXX):cmovle、cmovl、cmove、cmovne、cmovge、cmovg
注意:只有当条件码满足所需要的约束时,才会更新目的寄存器的值。
7、call指令将返回地址入栈,然后跳到目的地址。ret指令从这样的过程调用中返回。
8、pushl和popl指令实现了入栈和出栈。执行pushl和popl指令时,处理器的行为是不确定的,因为要入栈的寄存器会被同一条指令修改。通常有两种约定:
(1)压入/弹出%esp的原始值 (2)压入/弹出%esp-/+4后的值
9、halt指令停止指令的执行。对于Y86来说,执行halt指令会导致处理器停止,并将状态码设置为HLT。
-
指令编码
1、每条指令的第一个字节表明指令的类型。这个字节分为两个部分,每部分4位:高4位是代码部分,低4位是功能部分。功能值只有在一组相关指令共用一个代码时才有用。
(1)整数操作里代码部分均为6,功能部分区分addl,subl,andl,xorl (2)分支指令里代码部分均为7 (3)传送指令里代码部分均为2
2、8个程序寄存器中每个都有相应的0~7的寄存器标识符:
程序寄存器存在一个寄存器文件中,这个寄存器文件就是一个小的、以寄存器ID作为地址的随机访问存储器。当需要指明不应访问任何寄存器时,用ID值0xF表示。
3、分支指令和call指令没有寄存器操作数,就没有寄存器指示符字节。
irmovl、pushl、popl指令只需要一个寄存器操作数,将另一个寄存器指示符设为0xF。
4、指令集的一个重要性质就是字节编码必须有唯一的解释。
所有整数采用小端法编码。当指令按反汇编格式书写时这些字节就以相反的顺序出现。
-
Y86异常
出现异常时Y86处理器停止运行指令,也可以调用一个异常处理程序使其更完整。
Y86状态码:
-
Y86程序
1、Y86代码与IA32代码的主要区别:
(1)Y86可能需要多条指令来执行一条IA32指令所完成的功能。 (2)Y86没有伸缩寻址模式。
2、以“.”开头的词是汇编命令,他们告诉汇编器调整地址。创建Y86代码的唯一工具是汇编器。
-
指令集模拟器YIS
模拟Y86机器代码程序的执行,而不用试图去模拟任何具体处理器实现的行为。
逻辑设计和硬件控制语言HCL
-
要实现一个数字系统需要三个主要的组成部分:
(1)计算对位进行操作的函数的组合逻辑 (2)存储位的存储器元素 (3)控制存储器元素更新的时钟信号
-
逻辑门
AND && OR || NOT !
逻辑门只对单个位的数进行操作,而不是整个字。一旦一个门的输入变化,在短时间内,输出就会跟着变化。
-
组合电路和HCL布尔表达式
1、将逻辑门组合成一个网,构建计算块(组合电路)的限制。
注意:
- 两个以上的逻辑门的输出不能连接在一起,否则可能使线上信号矛盾,导致一个不合法的电压或电路故障。
- 这个网必须是无环的,否则会导致网络计算有歧义。
2、组合逻辑电路和c语言中逻辑表达式的区别:
- 组合电路的输出会持续地响应输入变化,c语言表达式只有在执行过程中被遇到才求值。
- C的逻辑表达式允许参数是任意整数,0是FALSE,其他任何值0的都是TRUE,逻辑门只对位值0和1操作。
- C的逻辑表达式可能被部分求值(第一个参数就能确定结果的就不会对第二个求值)。
-
字级的组合电路和HCL整数表达式
1、所有字级的信号都声明为int,不指定字的大小。
2、画字级电路时,中等粗度的线来表示携带字的每个位的线路,用虚线来表示布尔信号结果。
3、多路复用函数
通用格式: [ select_1(布尔表达式):expr_1(整数表达式) select_2:expr_2 ...... select_k:expr_k ]
选择表达式是顺序求值的,第一个求值为1的情况会被选中,选择表达式允许不互斥。
-
集合关系
通用格式:iexpr in {iexpr1,iexpr2,...,iexprk}
被测试的值iexpr和带匹配的值iexpr1~iexprk都是整数表达式。
-
存储器和时钟
1、时序电路:有状态,且在这个状态上进行计算的系统。
两类存储器设备:
- 时钟寄存器(寄存器):储存单个位或字,用时钟信号控制寄存器加载输入值。(保存程序计数器PC,条件代码CC和程序状态Stat)
- 随机访问储存器(储存器):储存多个字,用地址选择该读/写哪个字。(存储程序数据)
2、处理器还包括另外一个只读存储器,用来读指令。但在大多数实际系统中,这两个存储器被合并为一个具有双端口的存储器:一个用来读指令,一个用来读或写数据。
Y86的顺序实现
-
SEQ 顺序处理器
每个时钟周期上,SEQ执行一条完整指令所需的所有步骤。
-
将处理组织成阶段
六个基本阶段:
- 取指 从存储器读取指令字节,地址为程序计数器PC的值
- 译码 从寄存器读入最多两个操作数,得到valA或valB
- 执行 算术/逻辑单元要么执行指令指明的操作,计算存储器引用的有效地址,要么增加或减少栈指针。得到的值为valE。
- 访存 将数据写入存储器,或从存储器中读出数据,读出的值为valM。
- 写回 最多可以写两个结果到寄存器文件
- 更新PC 将PC设为下一条指令的地址
-
SEQ硬件结构
SEQ抽象视图画图惯例:
浅灰色方块表示硬件单元 控制逻辑块是用灰色圆角矩形表示的 线路的名字在白色椭圆中说明 宽度为字长的数据连接用中等粗度的线表示 宽度为字节或更窄的数据连接用细线表示 单个位的连接用虚线
-
SEQ的时序
SEQ的实现包括组合逻辑(不需要任何时序或控制)和两种存储器设备:
-
时钟寄存器 程序计数器和条件码寄存器
-
随机访问存储器 寄存器文件、指令存储器和数据存储器
指令存储器 只用来读指令(可以将这个单元看成是组合逻辑) 条件码寄存器 只在执行整数运算指令时装载 数据存储器 只在执行rmmovl、pushl或call时写入 寄存器文件 两个写端口允许每个时钟周期更新两个程序寄存器。(特殊寄存器ID 0xF表明此端口不应执行写操作)
-
-
SEQ阶段的实现
1、取指阶段:以PC为第一个字节的地址,一次读6个字节
icode 控制逻辑块计算指令 ifun 功能码
三个一位的信号(根据icode值计算)
instr_valid 发现不合法的指令 need_regids 包含寄存器指示符字节码 need_valC 包括常数字码
后五个字节是寄存器指示符字节和常数字的组合编码。
2、译码和写回阶段
都需要访问寄存器文件,根据四个端口的情况,判断应该读哪个寄存器产生信号valA、valB。
寄存器文件,支持同时进行两个读和两个写,每个端口有一个地址连接(寄存器ID)和一个数据连接(32根线路),既可以作为寄存器文件的输出字,又可以作为他的输入字。
3、执行阶段:
- 包括算数/逻辑单元(ALU),输出为valE信号:ALU通常作为加法器使用
- 包括条件码寄存器:每次运行产生零、符号、溢出、产生信号set_cc
4、访存阶段:读或者写程序数据
两个数据块产生存储器地址和存储器输入证据的值,两个产生控制信号表明应该是读还是写。
当执行读操作时,数据存储器产生valM。
根据icode,imem_error,instr_valid,dmem_error,从指令执行的结果计算状态码Stat。
5、更新PC阶段
产生程序计数器的新值,依据指令的类型和是否要选择分支,新的PC可能是valC、valM或者valP。
代码调试中的问题和解决过程
- 问题:实验楼实验中在“构建YIS环境”时,输入了
sudo ln -s /usr/lib/x86_64-linux-gnu/libtk8.6.so /usr/lib/libtk.so
命令。第一次输入时无提示,第二次输入时提示ln:无法创建符号链接"/usr/lib/libtk.so":文件已存在
,为什么要输入两遍?只输一遍可以吗? - 解决:
sudo ln -s 源文件 目标文件
命令功能为:为某一个文件或目录在另外一个位置建立一个同步的链接,类似Windows下的超级链接。建立符号链接时,如果[链接名]已经存在但不是目录,将不做链接。[链接名]可以是任何一个文件名(可包含路径),也可以是一个目录,并且允许它与“目标”不在同一个文件系统中。如果[链接名]是一个已经存在的目录,系统将在该目录下建立一个或多个与“目标”同名的文件,此新建的文件实际上是指向原“目标”的符号链接文件。
课后作业中的问题和解决过程
- 问题:看书上练习题时,看到p264 练习4.17时不明白答案是怎么写出来的,看前面的示例也看不懂,问了几个同学也说不知道。
- 解决:放弃了练习4.17,看练习4.18、练习4.19前面的示例时,发现了这类题的规律,其实就是对应着书上图4-18~图4-21,先找到对应的阶段和值,然后把对应的命令写上去……练习4.17、4.18、4.19、4.24其实都是这个套路,就只是细节上的不同。
本周代码托管截图
- 代码托管连接
- 第1~4周项目分文件夹时弄乱了已删除,从第五周开始存在新项目里。
- PS:git上学期用还好好的,这学期就总是会出问题,果然当初新建项目时很重要,新建的项目格式有问题之后调整就很费劲,总是会莫名其妙(其实是对git命令的含义不了解)的传不上去,或者全部覆盖(碰见问题按照百度解决时跟自己预期的结果不同)……还好我的代码一直留着,覆盖也只是重新传一次相同的,就是上传时间会改……
其他(感悟、思考等,可选)
本周我学习了Y86指令集、HCL硬件描述语言和Y86的顺序实现过程。Y86指令与IA32指令很相似,而且更少一些,两个相比较更便于记忆。HCL硬件描述语言的逻辑门的画法和之前学习过的数字电路差不多,时序电路工作原理也一致。Y86的顺序实现部分文字讲解很学术化,大致步骤已经了解,但是每一步的细节还在进一步理解中。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第零周 | 0/0 | 1/1 | 15/15 | 安装虚拟机 |
第一周 | 0/0 | 1/2 | 25/40 | 学习Linux命令 |
第二周 | 62/62 | 1/3 | 25/65 | 学习C编程 |
第三周 | 176/238 | 1/4 | 20/85 | 学习数的表示和计算 |
第五周 | 57/295 | 1/5 | 20/105 | 学习汇编语言,了解逆向思想 |
第六周 | 150/445 | 1/6 | 25/130 | 学习Y86处理器和HCL硬件描述语言 |