区别不同指令系统结构的主要因素: CPU中用来存储操作数的存储单元的类型
CPU中用来存储操作数的存储单元有三种:
根据存储操作数的存储单元将指令系统的结构分为三种类型:
对于不同类型的结构,操作数的位置、个数以及操作数的给出方式(显式或隐式)也会不同。
操作数的给出方式 | 说明 | 举例 |
---|---|---|
显式给出 | 用指令字中的操作数字段给出 | 通用寄存器结构 |
隐式给出 | 使用事先约定好的单元 | 堆栈结构(操作数是栈顶和次栈顶顶数据,通过PUSH/POP操作,结果保持在栈顶) 累加器结构(一个操作数默认在累加器中) |
不同指令系统结构的示例
例:表达式
Z=X+Y
在4种类型指令系统结构上的代码。假设:X、Y、Z均保存在存储器单元中,并且不能破坏X和Y的值。
堆 栈 | 累加器 | 寄存器(RM型) | 寄存器(RR型) |
---|---|---|---|
push X | load X | load R1,X | load R1,X |
push Y | add Y | add R1,Y | load R2,Y |
add | store Z | store R1,Z | add R3,R1,R2 |
pop Z | store R3,Z |
通用寄存器型结构是现代指令系统结构的主流,主要原因如下:
堆栈型和累加器型计算机的优点是指令字比较短,程序占用的空间比较小。但是,它们都有着难以克服的缺点。
通用寄存器型结构在灵活性和提高性能方面有明显的优势
根据ALU指令的操作数的两个特征对通用寄存器型结构进一步细分
ALU指令中存储器操作数的个数,可以是0~3中的某一个,为0表示没有存储器操作数。
ALU指令中存 储器操作数的个数 | ALU指令中操作数的最多个数 | 结构类型 | 机器实例 |
---|---|---|---|
0 | 3 | RR | MIPS,SPARC,Alpha,PowerPC,ARM |
1 | 2 | RM | IBM 360/370,Intel 80x86,Motorola 68000 |
1 | 3 | RM | IBM 360/370 |
2 | 2 | MM | VAX |
3 | 3 | MM | VAX |
根据ALU指令中存储器操作数的个数,可将通用寄存器型结构进一步细分为3种类型
3种通用寄存器型结构的优缺点如下表所示,表中(m,n)表示指令的n个操作数中有m个存储器操作数。
指令系统结构类型 | 优 点 | 缺 点 |
---|---|---|
寄存器-寄存器型(0,3) | 指令字长固定,指令结构简洁,是一种简单的代码生成模型,各种指令的执行时钟周期数相近。 | 与指令中含存储器操作数的指令系统结构相比,指令条数多,目标代码不够紧凑,因而程序占用的空间比较大。 |
寄存器-存储器型(1,2) | 可以在ALU指令中直接对存储器操作数进行引用,而不必先用load指令进行加载。 容易对指令进行编码,目标代码比较紧凑。 |
指令中的两个操作数不对称。 在一条指令中同时对寄存器操作数和存储器操作数进行编码,有可能限制指令所能够表示的寄存器个数。 指令的执行时钟周期数因操作数的来源(寄存器或存储器)不同而差别比较大。 |
存储器-存储器型(2,2) 或(3,3) | 目标代码最紧凑,不需要设置寄存器来保存变量。 | 指令字长变化大,特别是3操作数指令。 而且每条指令完成的工作也差别很大。 对存储器的频繁访问会使存储器成为瓶颈 这种类型的指令系统结构现在已不用了。 |
寻址方式:指令系统中如何形成所要访问的数据的地址。
寻址方式可以指明指令中的操作数是一个常数、一个寄存器操作数或者是一个存储器操作数。
对于存储器操作数来说,由寻址方式确定的存储器地址称为有效地址。
示例:Mem[Regs[R1]]:以寄存器R1中的内容作为地址的存储器单元中的内容
采用多种寻址方式可以显著地减少程序的指令条数,但可能增加计算机的实现复杂度以及指令的CPI。
立即数寻址方式和偏移寻址方式的使用频度最高。
立即数寻址方式主要用于ALU指令、比较指令、给寄存器装入常数等。
对指令系统的结构设计而言,首先要确定的是所有的指令还是只有部分指令具有立即数寻址方式。
大约1/4的load指令和ALU指令采用了立即数寻址。
需要注意的问题:物理地址空间的信息如何存放:
在确定哪些基本功能用硬件来实现时,主要考虑3个因素:速度、成本、灵活性。
完整性:在一个有限可用的存储空间内,对于任何可解问题,编制计算程序时,指令系统提供的指令足够使用。
要求指令系统功能齐全、使用方便
下表为许多指令系统结构都包含的一些指令类型
操作类型 | 实 例 |
---|---|
算术和逻辑运算 | 算术运算和逻辑操作:加,减,乘,除,与,或等 |
数据传输 | load,store |
控制 | 分支,跳转,过程调用和返回,自陷等 |
系统 | 操作系统调用,虚拟存储器管理等 |
浮点 | 浮点操作:加,减,乘,除,比较等 |
十进制 | 十进制加,十进制乘,十进制到字符的转换等 |
字符串 | 字符串移动,字符串比较,字符串搜索等 |
图形 | 像素操作,压缩/解压操作等 |
规整性:主要包括对称性和均匀性。
正交性:在指令中各个不同含义的字段,如操作类型、数据类型、寻址方式字段等,在编码时应互不相关、相互独立。
高效率:指指令的执行速度快、使用频度高。
兼容性:主要是要实现向后兼容,指令系统可以增加新指令,但不能删除指令或更改指令的功能。
在设计指令系统时,有两种截然不同的设计策略。(产生了两类不同的计算机系统 )
控制指令是用来改变控制流的。
能够改变控制流的指令
根据控制指令的使用频度:改变控制流的大部分指令是分支指令(条件转移)。
名 称 | 检测分支条件的方法 | 优 点 | 缺 点 |
---|---|---|---|
条件码 (CC) | 检测由ALU操作设置的一些特殊的位(即CC) | 可以自由设置分支条件 | 条件码是增设的状态。而且它限制了指令的执行顺序,因为要保证条件码能顺利地传送给分支指令。 |
条件寄存器 | 比较指令把比较结果放入任何一个寄存器,检测时就检测该寄存器。 | 简单 | 占用了一个寄存器 |
比较与分支 | 比较操作是分支指令的一部分,通常这种比较是受到一定限制的。 | 用一条指令(而不是两条)就能实现分支 | 当采用流水方式时,该指令的操作可能太多,在一拍内做不完。 |
在控制指令中,必须给出转移的目标地址,而转移目标地址的表示:
对于过程调用和返回
指令由两部分组成:操作码、地址码(地址信息)
操作码包括:操作种类、操作数描述。
指令格式的设计:确定指令字的编码方式,包括操作码字段和地址码(地址信息)字段的编码和表示方式。
指令格式的优化:如何用最短的位数来表示指令的操作信息和地址信息。
所有指令使用相同的代码位数,其最小码长等于:
L ˉ = l i = ⌈ log 2 n ⌉ \bar{L}=l_{i}=\left\lceil\log _{2} n\right\rceil Lˉ=li=⌈log2n⌉
式中 L ˉ \bar{L} Lˉ 是平均码长, l i l_{i} li 是第 i i i种指令的码长, n n n是指令总数。
优点:规整,译码简单。
缺点:浪费信息量。
例:已知 n = 15,求定长编码的最小平均码长。
L ˉ = ⌈ l o g 2 n ⌉ = ⌈ l o g 2 15 ⌉ = 4 \bar{L} = \left\lceil log_{2}n \right\rceil = \left\lceil log_{2}15 \right\rceil = 4 Lˉ=⌈log2n⌉=⌈log215⌉=4
基本原理:当用n个长度不等的代码分别代表n种发生概率不等的事件时,按照短代码给高概率事件、把长代码给低概率事件的原则分配,可使平均码长达到最低。
要采用Huffman编码法表示操作码,必须先知道各种指令在程序中出现的概率,通常可以通过已有典型程序统计得到。
根据Huffman编码法的原理,采用最优Huffman编码法表示的操作码的最短平均长度可通过下式计算,也就是操作码优化的程度可以用信息熵来衡量:
H = − ∑ i = 1 n p i ⋅ l o g 2 p i H = - \sum_{i=1}^{n} p_{i} \cdot log_{2} p_i H=−i=1∑npi⋅log2pi
其中: P i P_{i} Pi表示第 i i i种操作码在程序中出现的概率,表示用二进制编码表示 n n n个码点时,理论上的最短平均编码长度 。
固定长操作码相对于最优Huffman操作码的信息冗余量为:
R = 1 − − ∑ i = 1 n p i ⋅ l o g 2 p i ⌈ log 2 n ⌉ R = 1 - \frac{- \sum_{i=1}^{n} p_{i} \cdot log_{2} p_i}{\left\lceil\log _{2} n\right\rceil} R=1−⌈log2n⌉−∑i=1npi⋅log2pi
具体的**构造huffman树的方法**
Huffman编码的操作码优缺点:
为了便于分级译码,一般都采用等长扩展码。(在早期的计算机上)
例如:15/15/15法和8/64/512法
如果指令字的宽度固定,地址码的长度和个数固定,则操作码的缩短不能带来好处,只是使指令字中出现空白浪费。