指令系统的设计

指令系统是计算机系统结构的主要内容,是软硬件交界面的主要部分。

指令系统结构的分类

区别不同指令系统结构的主要因素:CPU中用来存储操作数的存储单元的类型。 CPU中用来存放操作数的存储单元主要有三种:堆栈、累加器、通用寄存器组。据此,可以把指令系统的结构分为堆栈型结构、累加器型结构以及通用寄存器型结构。 在通用寄存器型结构中,根据操作数的来源不同,又可以进一步分为寄存器-存储器型结构(简称RM结构)和寄存器-寄存器型结构(RR结构)。RM结构的操作数可以来自存储器,而RR结构的操作数则都是来自通用寄存器组的。由于在RR结构中,只有load指令和store指令能够访问存储器,所有也称为load-store结构。 对于不同类型的结构,指令系统中操作数的位置、个数以及操作数的给出方式(显式或隐式)是不同的。显式给出是用指令字中的操作数字段给出的隐式给出则是使用事先约定好了的单元。在堆栈型结构中,操作数都是隐式的,即堆栈的栈顶和次栈顶中的数据,运算后的结果写入栈顶。在这种结构中,只能通过push/pop指令访问存储器。在累加器型结构中,其一个操作数是隐式的,即累加器,另一个操作数则是显式给出的,是一个存储器单元。运算结果送回累加器。在通用寄存器型结构中,所有操作数都是显式给出的,它们或者来自通用寄存器组,或者有一个操作数来自存储器。运算结果写入通用寄存器组。 例如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

堆栈型和累加器型计算机的优点是指令字比较短,程序占用的控件比较小。但是,它们都有着难以克服的缺点。在堆栈型机器中,不能随机地访问堆栈,难以生成有效的代码,而且对栈顶的访问是个瓶颈。而在累加器型机器中,由于只有一个中间结果暂存区(累加器),所以需要频繁地访问存储器。

现在大多数计算机采用了通用寄存器型结构。通用寄存器型结构在灵活性和提高性能方面有明显的优势,主要体现在:

  • 寄存器的访问速度比存储器快很多;

  • 对编译器而言,能更加容易、有效地分配和使用寄存器;

  • 寄存器可以用来存放变量: 1.由于寄存器比存储器快,所以将变量分配给寄存器能加快程序的执行速度; 2.能够减少对存储器的访问; 3.可以用更少的地址位(相对于存储器地址)来对寄存器进行寻址,从而有效地减少程序的目标代码所占用的空间。

还可以根据ALU指令的操作数的两个特征来对通用寄存器结构进行进一步的细分:

  • 一个是ALU指令的操作数: 1.有三个操作数的指令:包含两个源操作数和一个目的操作数。 2.有两个操作数的指令:其中一个操作数既可以是源操作数,又可以作为目的操作数。

  • 另一个特征是ALU指令中存储器操作数的个数:它可以是0~3中的某一个值,为0表示没有存储器操作数。

基于上述ALU指令的两个特性及其组合,可以得到5种组合:

ALU指令中存储器操作数的个数
ALU指令中操作数的最多个数
结构类型
机器实例

0

3

RR

MIPS,SPARC,Alpha,PowerPC,ARM

1

2

RM

IBM360/370,Intel 80×86,Motorola 68000

1

3

RM

IBM360/370

2

2

MM

VAX

3

3

MM

VAX

通用寄存器型结构进一步细分为三种类型:寄存器-寄存器型(RR型)、寄存器-存储器型(RM型)和存储器-存储器型(MM型)。优缺点如下表(表中(m,n)表示指令的n个操作数中有m个存储器操作数):

指令系统结构类型
优点
缺点

寄存器-寄存器型(0,3)

指令字长固定,指令结构简洁,是一种简单的代码生成模型,各种指令的执行时钟周期数相近

与指令中含存储器操作数的指令系统结构相比,指令条数多,目标代码不够紧凑,因而程序占用的空间比较大

寄存器-存储器型(1,2)

可以在ALU指令中直接对存储器操作数进行引用,而不必先用load指令进行加载。容易对指令进行编码,目标代码比较紧凑

指令中的两个操作数不对称。在一条指令中同时对寄存器操作数和存储器操作数进行编码,有可能限制指令所能够表示的寄存器个数。指令的执行时钟周期数因操作数的来源(寄存器或存储器)不同而差别比较大

存储器-存储器型(2,2)或(3,3)

目标代码最紧凑,不需要设置寄存器来保存变量

指令字长变化很大,特别是3操作数指令。而且每条指令完成的工作也差别很大。对存储器的频繁访问会使存储器成为瓶颈。这种类型的指令系统结构现在已不用了

# 寻址方式

寻址方式是指指令系统如何形成所要访问的数据的地址。

  • 寻址方式可以指明指令中的操作数是一个常数、一个寄存器操作数或者是一个存储器操作数。

  • 对于存储器操作数来说,由寻址方式确定的存储器地址称为有效地址。

一些操作数寻址方式(左箭头代表赋值操作,Mem表示存储器,Regs表示寄存器组):

寻址方式
指令实例
含义

寄存器寻址

ADD R1,R2

Regs[R1]←Regs[R1]+Regs[R2]

立即数寻址

ADD R3,#6

Regs[R3]←Regs[R3]+6

偏移寻址

ADD R3,120(R2)

Regs[R3]←Regs[R3]+Mem[120+Regs[R2]]

寄存器间接寻址

ADD R4,(R2)

Regs[R4]←Regs[R4]+Mem[Regs[R2]]

索引寻址

ADD R4,(R2+R3)

Regs[R4]←Regs[R4]+Mem[Regs[R2]+Regs[R3]]

直接寻址或绝对寻址

ADD R4,(1010)

Regs[R4]←Regs[R4]+Mem[1010]

存储器间接寻址

ADD R2,@(R4)

Regs[R2]←Regs[R2]+Mem[Mem[Regs[R4]]]

自增寻址

ADD R1,(R2)+

Regs[R1]←Regs[R1]+Mem[Regs[R2]],Regs[R2]←Regs[R2]+d

自减寻址

ADD R1,-(R2)

Regs[R2]←Regs[R2]-d,Regs[R1]←Regs[R1]+Mem[Regs[R2]]

缩放寻址

ADD R1,80(R2)[R3]

Regs[R1]←Regs[R1]+Mem[80+Regs[R2]+Regs[R3]*d]

采用多种寻址方式可以显著地减少程序的指令条数,但可能增加计算机的实现复杂度以及指令的CPI。

各种寻址方式的使用情况统计结果:

立即数寻址方式主要用于ALU指令、比较指令和用于给寄存器装入常数等。

表示寻址方式的方法有两种:

  • 一种是隐含在指令的操作码中; 适合:处理机采用load-store结构,寻址方式只有很少几种。

  • 一种是在指令字中设置专门的寻址字段,用以直接指出寻址方式。 特点:灵活,操作码短,但需要设置专门的寻址方式字段,而且操作码和寻址方式字段合起来所需要的总位数可能会比隐含方法的总位数多。 适合:处理机具有多种寻址方式,且指令有多个操作数。

一个需要注意的问题:关于物理地址空间的信息存放。如何在存储器中存放这些不同宽度的信息呢?以IBM370为例:

  • 信息有字节、半字(双字节)、单字(4字节)和双字(8字节)等宽度。

  • 主存宽度为8个字节。采用按字节编址,各类信息都是用该信息的首字节地址来寻址。

允许它们任意存储:

  • 很可能会出现一个信息跨存储字边界而存储于两个存储单元中。 信息宽度不超过主存宽度的信息必须存放在一个存储字内,不能跨边界:

  • 必须做到:信息在主存中存放的起始地址必须是该信息宽度(字节数)的整数倍(信息存储的整数边界概念)

  • 满足以下条件: 1.字节信息的起始地址为:×…×××× 2.半字信息的起始地址为:×…×××0 3.单字信息的起始地址为:×…××00 4.双字信息的起始地址为:×…×000

  • 存在存储空间会浪费 ,但保证访问速度。

指令系统的设计和优化

指令系统设计的基本原则

指令系统的设计:

  • 首先考虑所应实现的基本功能,确定哪些基本功能应该由硬件实现,哪些功能由软件实现比较合适。

  • 包括 1.指令的功能设计 2.指令的格式设计

在确定哪些基本功能用硬件来实现时,主要考虑3个因素:速度、成本、灵活性。

  • 硬件实现的特点:速度快、成本高、灵活性差。

  • 软件实现的特点:速度慢、价格便宜、灵活性好。

对指令系统的基本要求:完整性、规整性、正交性、高效率和兼容性。

  • 完整性:在一个有限可用的存储空间内,对于任何可解的问题,编制计算程序时,指令系统所提供的指令足够使用。

  • 规整性:主要包括对称性和均匀性。 1.对称性:所有与指令系统有关的存储单元的使用、操作码的设置等都是对称的。 2.均匀性:指对于各种不同的操作数类型、字长、操作种类和数据存储单元,指令的设置都要同等对待。

  • 正交性:在指令中各个不同含义的字段,如操作类型、数据类型、寻址方式字段等,在编码时应互不相关、相互独立。

  • 高效率:指指令的执行速度快、使用频度高。

  • 兼容性:主要是要实现向后兼容,指令系统可以增加新指令,但不能删除指令或更改指令的功能。

在设计系统时,有两种截然不同的设计策略,因而产生了两类不同的计算机系统:

  • CISC(复杂指令系统计算机):增强指令功能,把越来越多的功能交由硬件来实现,并且指令的数量也是越来越多。

  • RISC(精简指令系统计算机):尽可能地把指令系统简化,不仅指令的条数少,而且指令的功能也比较简单。

控制指令

控制指令是用来控制指令流的。

  • 跳转:当指令是无条件改变控制流时,称之为跳转指令。

  • 分支:当控制指令是有条件改变控制流时,则称之为分支指令。

能够改变控制流的指令:

  • 跳转

  • 分支

  • 过程调用

  • 过程返回

控制指令的使用频度:

指令类型
使用频度(整型平均/%)
使用频度(浮点平均/%)

调用/返回

19

8

跳转

6

10

分支

75

82

改变控制流的大部分指令是分支指令(条件转移)。

表示分支条件的方法及其优缺点:

名称
检测分支条件的方法
优点
缺点

条件码(CC)

检测由ALU操作设置的一些特殊的位(即CC)

可以自由设置分支条件

条件码是增设的状态,而且它限制了指令的执行顺序,因为它们要保证条件码能顺利地传送给分支指令

条件寄存器

比较指令把比较结果放入任何一个寄存器,检测时是就检测该寄存器

简单

占用一个寄存器

比较与分支

比较操作是分支指令的一部分,通常这种比较是受到一定限制的

用一条指令(而不是两条)就能实现分支

当采用流水方式时,该指令的操作可能太多,在一拍内做不完

转移目标指令的表示

  • 最常用的方法:是在指令中提供一个偏移量,由该偏移量和程序计数器(PC)的值相加而得出目标地址。这种寻址方式叫做PC相对寻址。

  • 优点: 1.有效减少表示该目标地址所需要的位数。 2.位置无关(代码可被装载到主存的任意位置执行)。

  • 关键:确定偏移量字段的长度。

过程调用和返回

  • 除了要改变控制流之外,可能还要保存机器状态。至少也得保存返回地址(放在专用的链接寄存器或堆栈中)。

  • 过去有些指令系统结构提供了专门的保存机制来保存许多寄存器的内容。

  • 现在较新的指令系统结构则要求由编译器生成load和store指令来保存或恢复寄存器的内容。

指令操作码的优化

  • 指令由两部分组成:操作码、地址码

  • 指令格式的设计:确定指令字的编码方式,包括操作码字段和地址码字段的编码和表示方式。

  • 指令格式的优化:如何用最短的位数来表示指令的操作信息和地址信息。

赫夫曼编码

  • 基本思想:当各种事件发生的概率不均等时,可以对发生概率最高的事件用最短的位数(时间)来表示(处理),而对于出现概率较低的事件,则可以用较长的位数(时间)来表示(处理),从而使总的平均位数(时间)缩短。

  • 构造哈夫曼树的方法:将各事件按其使用频度从小到大依次排列。每次从中选择两个频度值最小的结点,将其合并成一个新的结点,并把新结点画在所选结点的上面,然后用两条边把新节点分别与那两个节点相连。新节点的频度是所选两个节点的频度值的和。把新节点与其他剩余未结合的节点一起,再以上面的步骤进行处理,反复进行,直到全部节点都结合完毕、形成根节点为止。

  • 操作码优化的程度可以用信息熵来衡量。H=-∑PiLog2Pi,它表示用二进制编码表示n个码点时,理论上的最短平均编码长度。

  • 优缺点:可以减少操作码的平均位数,但所获得的编码是变长度的,不规整,不利于硬件处理。

等长扩展码

在早期的计算机上,为了便于分级译码,一般都采用等长扩展码。

定长操作码

  • 固定长度的操作码:所有指令的操作码都是同一的长度(如8位)。

  • 保证操作码的译码速度、减少译码的复杂度。

  • 以程序的存储空间为代价来换取硬件实现上的好处。

指令字格式的优化

  • 利用操作码缩短所带来的好处。

考虑因素

  • 计算机中寄存器的个数和寻址方式的数目对机器的指令字长有很大的影响;

  • 指令字的平均长度增加了,程序的平均长度也就增加了;

  • 在指令系统的设计中,要在指令字长与寄存器的个数以及寻址方式的个数之间进行折中。

指令系统的3种编码格式:可变长度编码格式、固定长度编码格式、混合型编码格式。

指令系统的发展和改进

沿CISC方向发展和改进指令系统

  • CISC指令系统的一大特点:指令数量多、功能多样

  • 增强指令功能主要是从以下3个方面着手: 1.面向目标程序增强指令功能 2.面向高级语言的优化实现来改进指令系统 3.面向操作系统的优化实现来改进指令系统

面向目标程序增强指令功能

  • 对大量的目标程序及其执行情况进行统计分析,找出那些使用频度高、执行时间长的指令或指令串。对于使用频度高的指令,用硬件加快其执行;对于使用频度高的指令串,用一条新的指令来替代。

  • 既能减少目标程序的执行时间,也能有效地缩短程序的长度。

  • 可以从以下几个方面来改进: 1.增强运算型指令的功能 2.增强数据传送指令的功能 3.增强程序控制指令的功能

面向高级语言的优化实现来改进指令系统

面向高级语言的优化实现来改进指令系统(缩小高级语言与机器语言的语义差距) 高级语言与一般的机器语言的语义差距非常大,为高级语言程序的编译带来了一些问题。 (1)编译器本身比较复杂; (2)编译生成的目标代码比较难以达到很好的优化。

  • 增强对高级语言和编译器的支持 1.对高级语言中使用频度高、执行时间长的语句,增强有关指令的功能,加快这些指令的执行速度,或者增加专门的指令,可以达到减少目标程序的执行时间和减少目标程序长度的目的。 2.增强系统结构的规整性,减少系统结构中的各种例外情况。

  • 高级语言计算机 (一种比较激进的方法) 1.间接执行高级语言机器:高级语言作为机器的汇编语言。 2.直接执行高级语言的机器:直接把高级语言作为机器语言。

  • 采用“比较简单的系统结构+软件”的做法能够在较低成本和复杂度的前提下,提供更高的性能和灵活性。

面向操作系统的优化实现来改进指令系统

  • 操作系统和计算机系统结构是紧密联系的,操作系统的实现在很大程度上取决于系统结构的支持。

  • 指令系统对操作系统的支持主要有: 1.处理机工作状态和访问方式的切换; 2.进程的管理和切换; 3.存储管理和信息保护; 4.进程的同步与互斥,信号灯的管理等。 支持操作系统的有些指令属于特权指令,一般用户程序是不能使用的。

沿RISC方向发展和改进指令系统

CISC指令系统结构存在的问题:

  • 各种指令的使用频度相差悬殊,许多指令很少用到。

  • 指令系统庞大,指令条数很多,许多指令的功能又很复杂。 1.占用了大量的芯片面积(如占用CPU芯片总面积的一半以上),给VLSI设计造成很大的困难; 2.增加了研制时间和成本,容易造成设计错误。

  • 许多指令由于操作繁杂,其CPI值比较大,执行速度慢。采用这些复杂指令有可能使整个程序的执行时间反而增加。

  • 由于指令功能复杂,规整性不好,不利于采用流水技术来提高性能。

设计RISC机器遵循的原则:

  • 指令条数少、指令功能简单。只选取使用频度很高的指令,在此基础上补充一些最有用的指令;

  • 采用简单而又统一的指令格式,并减少寻址方式;指令字长都为32位或64位;

  • 指令的执行在单个机器周期内完成;(采用流水线机制)

  • 只有load和store指令才能访问存储器,其它指令的操作都是在寄存器之间进行;(即采用load-store结构)

  • 大多数指令都采用硬连逻辑来实现;

  • 强调优化编译器的作用,为高级语言程序生成优化的代码;

  • 充分利用流水技术来提高性能。

操作数的类型和大小

表示操作数类型的方法有两种

  • 由指令中的操作码指定操作数的类型。

  • 给数据加上标识,由数据本身给出操作数类型。 1.优点:简化指令系统,可由硬件自动实现一致性检查和类型转换,缩小了机器语言与高级语言的语义差距,简化编译器等。 2.缺点:由于需要在执行过程中动态检测标志符,动态开销比较大,所以采用这种方案的机器很少见。

操作数的大小:操作数的位数或字节数。 主要的大小:字节(8位)、半字(16位)、字(32位)、和双字(64位)。

  • 字符:用ASCII码表示,为一个字节大小。

  • 整数:用二进制补码表示,其大小可以是字节、半字或单字。

  • 浮点操作数:单精度浮点数(1个字)、双精度浮点数(双字)。一般都采用IEEE 754浮点标准。

  • 十进制操作数类型 1.压缩十进制或二进制编码十进制(BCD码):用4位二进制编码表示数字0~9,并将两个十进制数字合并到一个字节中存储。 2.非压缩十进制:将十进制数直接用字符串来表示。

MIPS指令系统结构

介绍MIPS64的一个子集,简称为MIPS。

MIPS的寄存器

1.32个64位通用寄存器(GPRs)

  • R0,R1,…,R31

  • 也称为整数寄存器

  • R0的值永远是0

2.32个64位浮点数寄存器(FPRs)

  • F0,F1,…,F31

  • 用来存放32个单精度浮点数(32位),也可以用来存放32个双精度浮点数(64位)。

  • 存储单精度浮点数(32位)时,只用到FPR的一半,其另一半没用。

3.一些特殊寄存器

  • 它们可以与通用寄存器交换数据。

  • 例如浮点状态寄存器:用来保存有关浮点操作结果的信息。

MIPS的数据表示

1.MIPS的数据表示

  • 整数 字节(8位) 半字(16位) 字(32位) 双字(64位)

  • 浮点数 单精度浮点数(32位) 双精度浮点数(64位)

2.字节、半字或者字在装入64位寄存器时,用零扩展或者用符号位扩展来填充该寄存器的剩余部分。装入以后,对它们将按照64位整数的方式进行运算。

MIPS的数据寻址方式

1.立即数寻址与偏移量寻址;立即数字段和偏移量字段都是16位的。 2.寄存器间接寻址是通过把0作为偏移量来实现的; 3.16位绝对寻址是通过把R0(其值永远为0)作为基址寄存器来完成的; 4.MIPS的存储器是按字节寻址的,地址为64位; 5.所有存储器访问都必须是边界对齐的。

MIPS的指令格式

1.寻址方式编码到操作码中 2.所有的指令都是32位的 3.操作码占6位 4.3种指令格式:3种格式中,同名字段的位置固定不变。

MIPS的操作

1.MIPS指令可以分为四大类

  • load和store

  • ALU操作

  • 分支与跳转

  • 浮点操作

2.符号的意义

  • x←ny:从y传送n位到x

  • x,y←z:把z传送到x和y

  • 下标:表示字段中具体的位; ①对于指令和数据,按从最高位到最低位(即从左到右)的顺序依次进行编号,最高位为第0位,次高位为第1位,依此类推。 ②下标可以是一个数字,也可以是一个范围。     例如:Regs[R4]0:寄存器R4的符号位 Regs[R4]56-63:R4的最低字节

  • Mem:表示主存; 按字节寻址,可以传输任意个字节。

  • 上标:用于表示对字段进行复制的次数。 例如:0 32:一个32位长的全0字段

  • 符号##:用于两个字段的拼接,并且可以出现在数据传送的任何一边。

MIPS的控制指令

由一组跳转和一组分支指令来实现控制流的改变。

MIPS的浮点操作

浮点指令对浮点寄存器中的数据进行操作,并由操作码指出操作数是单精度还是双精度的。 浮点操作包括加、减、乘、除,分别有单精度和双精度指令。

《计算机系统结构教程(第2版)》张晨曦 王志英 等 著

Last updated