计算机指令集结构
指令集结构的分类
- 区别不同指令集结构的主要因素:CPU中用来存储操作数的存储单元类型
- CPU中用来存储操作数的存储单元的主要类型:
a) 堆栈
b) 累加器
c) 通用寄存器组
- 将指令集结构分为三种类型
a) 堆栈结构
b) 累加器结构
c) 通用寄存器结构:
- i. 寄存器-寄存器结构(RR结构)所有操作数都是来自通用寄存器
优点:指令字长固定,指令结构间接,是一种简单的代码生成模型,各种指令的执行时钟周期接近
缺点:与指令中含存储器操作数的指令集结构相比,指令条数多,目标代码不够紧凑,因而程序占用的空间比较大
- ii. 寄存器-存储器结构(RM结构)操作数可以来自存储器
优点:可以在ALU指令中直接对存储器操作数进行引用,而不必先用load指令进行加载。容易对指令进行编码,目标代码比较紧凑。
缺点:指令中两个操作数不对称。在一条指令中同时对寄存器操作数和存储器操作数进行编码,有可能限制指令所能够表示的存储器个数。指令的执行时钟周期因操作数的来源(寄存器或存储器)不同而差别较大。
- iii. 存储器-存储器结构(MM结构)
优点:目标代码最紧凑,不需要设置寄存器来保存变量
缺点:指令字长变化很大,特别是3操作数指令。而且每条指令完成的工作也差别很大。对存储器的频繁访问会使存储器成为瓶颈。这种类型的指令集结构现在已经不用了。
- 对于不同类型的指令集结构,操作数位置、个数以及操作数的给出方式(显式或隐式)也会不同。
显示给出:用指令字的操作数字段给出
隐式给出:使用事先约定好的存储单元
- 4种指令集结构的操作数的位置以及结果的去向
- 通用寄存器结构(现代指令集结构的主流)
在灵活性和提高性能方面有明显的优势
- 根据ALU指令的操作数的两个特征对通用寄存器型指令集结构进一步细分
ALU指令的操作数个数
a) 3个操作数的指令:两个源操作数、一个目的操作数
b) 3个操作数的指令:其中一个操作数即作为源操作数,有作为目的操作数
寻址方式
- 隐含寻址:在指令中隐含操作数的地址
- 立即数寻址:在指令中直接给出操作数
- 直接寻址:在指令中直接给出操作数的地址EA=A
- 间接寻址:在指令中给出指向操作数地址的向量地址EA=[A]
- 寄存器寻址:在指令中给出存储操作数的寄存器EA=R
- 寄存器间接寻址:EA=[R]
- 相对寻址:EA=A+X
- 基址寻址:EA=[BR]+X
- 变址寻址:EA=[IX]+X
立即数寻址和偏移寻址的使用频度最高
指令集结构的功能设计
- 指令集结构的功能设计:确定软、硬件功能分配,即确定哪些基本功能应由硬件实现,哪些功能由软件实现比较合适。
- 确定哪些基本功能用硬件实现时,主要考虑:速度、成本、灵活性
硬件实现的特点:速度快、成本高、灵活性差
软件实现的特点:速度慢、价格便宜、灵活性好
- 对指令集的基本要求:完整性、规整性、高效率、兼容性
a) 完整性:在一个有限可用的存储空间内,对于任何可解的问题,编制计算程序时,指令集所提供的指令足够用。要求指令集功能齐全、使用方便。
b) 规整性:主要包括对称性和均匀性
对称性:所有与指令集有关的存储单元的使用、操作码的设置都是对称的。
均匀性:指对于各种不同操作数类型、字长、操作种类和数据存储单元,指令的设置都要同等对待。
c) 规整性:指令的执行速度快、使用频度高
- 在设计指令集结构时,有两种截然不同的设计策略
CISC(Complex Instruction Set Computer)复杂指令集计算机:增强指令功能,把越来越多的功能交由硬件来实现,并且指令的数量也是越来越多。
RISC(Reduced Instruction Set Computer)精简指令集计算机:尽可能地把指令集简化,不仅指令的条数少,而且指令的功能也比较简单。
CISC指令集的功能设计
- CISC结构追求的目标:强化指令功能,减少程序的指令条数,以达到提高性能的目的。
- 增强指令功能主要是从以下几个方面入手:
a) 面向目标程序增强指令功能:
b) 面向高级语言的优化来改进指令集:(缩小高级语言与机器语言的语义差距)
高级语言与一般的机器语言的语义差距非常大,为高级语言的程序的编译带来了一些问题:
- i. 编译器本身比较复杂
- ii. 编译生成的目标代码比较难以达到很好的优化
高级语言计算机
- 间接执行高级语言机器
高级语言成为机器的汇编语言,这时高级语言和机器语言是一一对应的。用汇编的方法把高级语言源程序翻译成机器语言
- 直接执行高级语言机器
直接把高级语言作为机器语言,直接由硬件对高级语言源程序的语句逐条进行解释执行。这时既不用编译,也不用汇编。
面向操作系统的优化实现改进指令集
OS和计算机系统结构是紧密联系的,OS的实现在很大程度上取决于系统结构的支持。
指令集对OS的支持主要有:
- 处理机工作状态和访问方式的切换
- 进程的管理和切换
- 存储管理和信息保护
- 进程的同步与互斥,信号灯的管理等
支持OS的有些指令属于特权指令,一般用户程序是不能使用的。
RISC指令集结构的功能设计
- CISC指令集结构存在的问题
a) 各种指令的使用频度相差悬殊
b) 指令集庞大,控制条数很多,许多指令的功能又很复杂,使得控制器硬件非常复杂。
c) 许多指令由于操作繁杂,其CPI值比较大,执行速度慢。采用这些复杂指令有可能使整个程序的执行时间反而增加
d) 由于指令功能复杂,规整性不好,不利于采用流水技术来提高性能。
- 设计RISC机器遵循的原则
a) 指令条数少而简单
b) 采用简单而统一的指令格式,并减少寻址方式;指令字长都为32位或64位。
c) 指令的执行在单个机器周期内完成(流水线机制)
d) 只有load和store指令才能访问存储器,其他指令的操作都在寄存器之间进行(即采用load-store结构)
e) 大多数指令都采用硬连逻辑来实现
f) 强调优化编译器的作用,为高级语言程序生成优化的代码
g) 充分利用流水技术来提高性能
控制指令
- 控制指令是用来改变控制流的
- 能够改变控制流的指令:分支、跳转、过程调用、过程返回
- 控制指令的使用频度
指令类型 |
使用频度 |
|
整型平均 |
浮点平均 |
|
调用/返回 |
19% |
8% |
跳转 |
6% |
10% |
分支 |
75% |
82% |
改变控制流的大部分指令是分支指令(条件转移)
- 常用的三种表示条件分支的方法及其优缺点
a) 条件码(CC):检测由ALU操作设置的一些特殊的位即(CC)
优点:可以自由设置分支条件
缺点:条件码是增设的状态,而且它限制了指令的执行顺序,因为要保证条件码能顺利地传送给分支指令
b) 条件寄存器:比较指令把比较结果放入条件寄存器
优点:简单
缺点:占用了一个寄存器
c) 比较与分支:比较操作是分支指令的一部分,通常这种比较指令是受到一定限制的
优点:用一条指令就能实现分支
缺点:当采用流水方式时,该指令的操作可能太多在一拍内做不完
- 转移目标地址的表示
在指令中提供偏移量X,PC=PC+X
优点:有效减少表示该目标地址所需要的位数、位置无关
关键:确定偏移量字段的长度
模拟结果表明:采用4-8位偏移量字段(以指令字为单位)就能表示大多数控制指令的转移目标地址了。
- 过程调用和返回
a) 除了要改变控制流外,还可能要保存机器状态,至少也得保存返回地址(放在专用的链接寄存器或堆栈中)
b) 过去有些指令集结构提供了专门的保存机制来保存许多寄存器的内容
c) 现在较新的指令集结构则要求由编译器生成load和store指令来保存或恢复寄存器的内容
操作数
- 数据表示:计算机硬件能够直接试别、指令集可以直接调用的数据类型
- 数据结构:由软件进行处理和实现的各种数据类型
- 表示操作数类型
a) 由指令中的操作码指定操作数的类型
b) 带标志的数据表示表示。给数据加上标识,由数据本身给出操作数类型
优点:简化指令集,可由硬件自动实现一致性检查和类型转换,缩小了机器语言与高级语言的差距,简化编译器
缺点:由于需要在执行过程中动态检测标识符,动态开销较大,所以采用这种方案的机器很少见
指令格式
- 指令的组成:操作码、地址码
- 指令格式的设计:确定指令字的编码方式,包括操作码字段和地址码字段的编码和表示方式。
- 操作码的编码
a) Huffman编码法
b) 固定长度编码法
- 两种表示寻址方式的方法
a) 将寻址方式编码于操作码中,由操作码描述相应操作的寻址方式
b) 设置专门的地址描述符,由地址描述符表示相应操作数的寻址方式
- 考虑因素
a) 机器中寄存器的个数和寻址方式的数目对指令平均字长的影响以及它们对目标代码大小的影响
b) 所设计的指令格式便于硬件处理,特别是流水实现
c) 指令字长应该是字节的整数倍,而不能是随意的位数
- 指令集的三种编码格式
a) 变长编码格式
操作码 |
地址描述符1 |
地址码1 |
…… |
地址描述符n |
地址码n |
当指令集的寻址方式和操作种类很多时,这种编码格式是最好的。用最少的二进制位来表示目标代码,可能会使各条指令的字长和执行时间相差很大
b) 定长编码格式
操作码 |
地址码1 |
地址码2 |
地址码3 |
有效地较低译码的复杂度,大部分RISC指令集均采用这种编码格式。
c) 混合型编码方式
提供若干中固定的指令字长,以期达到既能减少目标代码长度,友能降低译码复杂度的目标。
MIPS指令集结构:MIPS架构是一种简洁、优化、具有高度扩展性的RISC架构。它的基本特点是:包含大量的寄存器、指令数和字符、可视的管道延时时隙,这些特性使MIPS架构能够提供最高每平方毫米性能和当今SoC设计中最低的能耗。
- MIPS的寄存器
a) 32个64位通用寄存器(GPRs)
b) 32个64位浮点数寄存器(FPRs)
c) 一些特殊寄存器(可以与通用寄存器交换数据)
- MIPS的数据表示
字节、半字或者字在装入64位寄存器时,用零扩展或者用符号位扩展来填充该寄存器的剩余部分。装入以后,对它们将按照64位整数的方式进行运算。
- MIPS的数据寻址方式
a) 立即数寻址与偏移量寻址(均为16bits)
b) 寄存器间接寻址是通过把0作为偏移量来实现的。
c) 16位绝对寻址是通过把R0(其值永远为0)作为基址寄存器来完成的
d) MIPS的存储器是按字节寻址的,地址为64bits
e) 所有存储器访问都必须是边界对齐的
MIPS的指令格式
- 寻址方式编码到操作码中
- 所有的指令都是32位的
- 操作码占6位
- 3种指令格式
a) I类指令
- i. 包括所有的load和store指令、立即数指令、分支指令、寄存器跳转指令、寄存器链接跳转指令。
- ii. 立即数字段为16位,用于提供立即数或偏移量
操作码0-5 |
rs6-10 |
rt11-15 |
立即数16-31 |
load指令
store指令
立即数指令
分支指令
寄存器跳转、寄存器跳转并链接
b) R类指令
- i. 包括ALU指令、专用寄存器读/写指令、move指令等
- ii. ALU指令
Regs[rd]ßRegs[rs] funct Regs[rt]
func为具体的运算操作编码
操作码0-5 |
rs6-10 |
rt11-15 |
rd16-20 |
sham21-25 |
func26-31 |
c) J类指令
- i. 包括跳转指令、跳转并链接指令、自陷指令、异常返回指令
- ii. 在这类指令中,指令字的低26位是偏移量,它与PC值相加形成跳转的地址
操作码0-5 |
与PC相加的偏移量 |
MIPS的操作
- MIPS指令分类
a) load & store
b) ALU操作
c) 分支与跳转
d) 浮点操作
- MIPS符号
从y传n位到x
把z传送到x、y
R4的最低字节
一个32位全长为0字段
用于两个字段的拼接
- ALU指令:寄存器-寄存器型(RR型)指令或立即数型
算数和逻辑操作:加、减、与、或、异或和移位等
- MIPS的控制指令
a) 由一组跳转和一组分支指令来实现控制流的改变
b) 典型的MIPS控制指令
- i. 跳转指令
- 根据跳转指令确定目标地址的方式不同以及跳转时是否链接,可以把跳转指令分成四种
- 确定目标地址的方式
- 跳转的两种类型
a) 简单跳转:PC=X
b) 跳转并链接:R31=PC,PC=X
- ii. 分支指令(条件转移)
- 分支条件由指令确定
- 提供一组比较指令,用于比较两个寄存器的值
- 优的分支指令可以直接判断寄存器的内容是否为负,或者比较两个寄存器是否相等
- 分支的目标地址
- 一条浮点条件分支指令:通过测试浮点状态 寄存器来决定是否进行分支
- MIPS的浮点操作
a) 由操作码指出操作数是单精度(SP)或双精度(DP)
- i. 后缀S:表示操作数是单精度浮点数
- ii. 后缀D:表示是双精度浮点数
b) 浮点操作:包括加减乘除,分别由单精度和双精度指令
c) 浮点数比较指令:根据比较结果设置浮点状态寄存器中的某一位,以便于后面的分支指令BC1T(若真则分支)或BC1F(若假则分支)测试该位,以决定是否分支