每条指令都会读取或修改处理器状态的某些部分
可以是用汇编代码写程序的人,也可以是产生机器级代码的编译器。
Y86程序用虚拟地址来引用存储器位置,硬件和操作系统软件联合起来将虚拟地址翻译成实际或物理地址
它表明程序执行的总体状态,会指示是正常运行还是出现了某种异常。
Y86指令集基本上是IA32指令集的一个子集,只包括四字节整数操作,寻址方式比较少,操作也较少。
汇编码表示和字节编码参见课本232页。
IA32的movl指令分为四种:
irmovl,rrmovl,mrmovl,rmmovl
前面的两个字母是在显式的指定源操作数和目的操作数的格式,第一位是源操作数,第二位是目的操作数。
可以是:
i-立即数
r-寄存器
m-存储器
可以是:
r-寄存器
m-存储器
※这里的存储器引用方式是简单的基址和偏移量形式,寻址方式不支持第二变址寄存器和任何寄存器值的伸缩
※两个操作数不能都是来自存储器,也不允许将立即数传送到存储器
addl 加
subl 减
andl 与
xorl 异或
并且它们只对寄存器数据进行操作(区别于IA32,后者还允许对存储器数据进行这些操作)。
这些指令会设置三个条件码:
ZF-零
SF-符号
OF-溢出
jmp 直接跳转
jle(SF^OF)|ZF 有符号数≤
jl SF^OF 有符号<
je ZF 相等/零
jne ~ZF 不相等/非零
jge ~(SF^OF) 有符号≥
jg ~(SF^OF)&~ZF 有符号>
cmovle
cmovl
cmove
cmovne
cmovge
cmovg
这些指令的格式与寄存器-寄存器传送指令rrmovl一样,但是只有当条件码满足所需要的约束时,才会更新目的寄存器的值。
call指令将返回地址入栈,然后跳到目的地址,ret指令从这样的过程调用中返回。
实现入栈和出栈
halt指令停止指令的执行,执行此指令会导致处理器停止,并将状态码设置为HLT。
类比IA32:hlt指令与之类似,但是IA32的应用程序不允许使用这条指令,因为它会导致整个系统暂停运行。
每条指令需要1-6个字节不等,每条指令的第一个字节表明指令的类型。
这个字节分为两个部分,每个部分4位:
比如:课本第233页,Y86指令集的功能码:
整数操作里代码部分均为6,功能部分区分addl,subl,andl,xorl
分支指令里代码部分均为7
传送指令里代码部分均为2
这里要注意rrmovl归到了传送指令里,前面说过它们有相同的指令代码
8个程序寄存器中每个都有相应的0~7的寄存器标识符,程序寄存器存在CPU中的一个寄存器文件中,这个寄存器文件就是一个小的、以寄存器id作为地址的随机访问存储器。
当需要指明不应访问任何寄存器时,用ID值0xF表示
指定一个或两个寄存器,例如rA或者rB。
这个字的用处:
1.irmovl的立即数数据
2.rmmol和mrmovl的地址指示符的偏移量
3.分支指令和调用指令的目的地址
注意事项
1.分支指令和调用指令的目的地址是一个绝对地址
2.所有整数采用小端法编码
※指令集的重要性质:
字节编码必须有唯一的解释
习题4.1的解答技巧:这道题只需要按照指令编码各个位上的值去对应即可,比如第一行,irmovl的指令是30f,目的操作数是%ebx,查表得3,源操作数是立即数15,转为16进制数为00 00 00 0f,小端法表示为0f 00 00 00,组合在一起即为30f30f000000。
习题4.2的解答技巧:这道题要注意划分数字为不同的指令。
Stat描述程序执行的总体状态
1. AOK 正常操作
2. HLT 处理器执行halt指令
3. ADR 遇到非法地址
4. INS 遇到非法指令
Y86——处理器停止运行指令。
更完整?调用一个异常处理程序
具体范例参见课本第238-239页
Y86和IA32代码对比来看,本质上两者相同,但是:
1.Y86有时需要两条指令来完成IA32一条指令就能完成的事
2.Y86没有伸缩寻址模式
(1)命令指明应该将代码或数据放在什么位置,以及该如何对齐
(2)以“.”开头的是汇编器命令
(3)创建Y86代码的唯一工具是汇编器,所以程序员必须执行本来通常交给编译器、链接器和运行时系统来完成的任务。
特指popl和pushl,在压入/弹出栈指针%esp的时候,有两种不同的约定:
1.压入/弹出%esp的原始值
2.压入/弹出%esp-/+4后的值
经过试验,发现默认压入弹出的都是原始值。
pushl在不同的x86模型之间有歧义,但是popl没有。
电子电路中,用1.0V左右的高电压表示逻辑1,用0.0V左右的低电压表示逻辑0.
1.逻辑门产生的输出,等于它们输入位值的某个布尔函数。
4.逻辑门总是活动的,输入变化输出很快就跟着变化。
对应EDA学习时的组合逻辑电路
这里面需要注意几个零碎的知识点:
多路复用函数用情况表达式来描述,具体格式如下:
[
select_1 : expr_1
select_2 : expr_2
……
]
从逻辑上讲,这些选择表达式是顺序求值的。
不同 选择表达式之间允许不互斥
判断集合关系的通用格式是:
iexpr in {iexpr1,iexpr2,...,iexprk}
iexpr等都是整数表达式。
对应EDA学习时的时序逻辑电路
(1)时钟寄存器(简称寄存器):储存单个位或字。
(2)随机访问储存器(简称储存器):储存多个字,用地址选择该读/写哪个字。
寄存器分为“硬件寄存器”和“程序寄存器”。
它会用时钟寄存器保存程序计数器PC,条件代码CC和程序状态Stat。
这一节学习的时候对比EDA课程中学习的Verilog语言的规则,大同小异,但是要注意迁移——把指令对应到位的操作上。
SEQ处理器
具体每一阶段执行的内容见书250页,根据每一步计算的题目在253页习题4.11,做这个题的时候最要紧是注意每个字符代表的含义是什么,才能进行正确的计算。这个题不难,就是有点麻烦,多看多理解。
这四种按照框架往里套即可。
有六个基本阶段,见上。具体关联参见258页图。
SEQ的实现包括组合逻辑和两种存储器设备:
1.时钟寄存器——程序计数器和条件码寄存器
2.随机访问存储器——寄存器文件、指令存储器和数据存储器
对于上面提到的五个硬件单元,可以分成两类:
1.组合逻辑——指令存储器
2.时序——剩下四个
剩下四个中:
条件码寄存器——只在执行整数运算指令时装载
数据存储器——只在执行rmmovl、pushl或call时写入
寄存器文件——两个写端口允许每个时钟周期更新两个程序寄存器。特殊寄存器?0xF表示此端口不应执行写操作。
※Y86指令集下的组织原则:
总结就是,用时钟来控制状态元素的更新,值通过组合逻辑传播。
halt指令:使处理器状态变为HLT,导致停止运行
以PC为第一个字节,读6个字节。
两个逻辑块(从第一个字节中分出,各四位)
icode-指令代码
ifun-指令功能
三个一位的信号(根据icode值计算)
instr_valid-发现不合法的指令
need_regids-包含寄存器指示符字节吗
need_valC-包括常数字吗
后五个字节是寄存器指示符字节和常数字的组合编码。
都需要访问寄存器文件,根据四个端口的情况,判断应该读哪个寄存器产生信号valA、valB
(1)包括算术/逻辑单元ALU,输出的是valE。
ALU常被用作加法器
(2)包括条件码寄存器
零,符号,溢出,产生信号set_cc
两个数据块产生存储器地址和存储器输入证据的值,两个产生控制信号表明应该是读还是写。
会产生程序计数器的新值。
这一章的内容总体学起来比较陌生,看起来很吃力,只能对着课本磕磕绊绊的去做,迁移出来的能力还不够,但是中间关于逻辑门计算的部分由于上学期有Verilog语言的底子,学习的时候可以用作类比,举一反三,从而这一部分的理解相对比较容易。
课本。
编译后查看目录下内容,可以看到已经有编译后的.yo文件,用vim进入后可以查看
课本第239页图4-7上的代码,在系统中叫做asum.yo,把它的内容打印在屏幕上:
可以看出来和课本240页的结果是一致的。
课本第251页图4-17,我先用建立了一个417.ys进入后,输入:
然���用make 417.yo编译,编译后用vim进入417.yo
当指令开始的位置固定在0的时候,后面的偏移地址都是确定的,所以所以指令的地址都可以说的确定的,所以出来的左边那些与书上的一致。
【疑问】
1.我看pdf中,YIS模拟器应该是有单独窗口的,但是我从指导书和网上都找不到怎么打开这个单独窗口,从网上下载的模拟器和qq群下载的都不能使,解压之后很多找不到打开方式的文件,联网搜索也没有找到,所以根本没有办法像pdf中那样方便的在窗口中查看,只能在命令行中运行。
2.验证书上HCL代码是什么意思?我输入了图4-17的代码,汇编后除了得出跟书上一样的结果外没有得到别的。
如果是指那些逻辑门的表达式,我的做法是按照电路和EDA的学习方式,通过真值表,画逻辑图,得出表达式,我觉得这没什么可证明的啊……