第四章 指令系统的设计原理和风格
本章属重点章。指令系统是计算机外特性的重要内容,本章主要介绍了两种不同风格的指令系统:RISC和CISC.在学习这两种指令系统之前,我们先了解一下什么是指令系统。
一、指令系统的设计(领会)
指令系统是指机器所具有的全部指令的集合。它反映了计算机所拥有的基本功能。它是机器语言程序员所看到的机器的主要属性之一。
通常我们说的加法指令、传输数据指令等等就是计算机的指令,这些指令就是告诉计算机从事某一特殊运算的代码,一种计算机系统确定的这些指令的集合我们就说它是这种机器的指令系统。
那么指令系统的设计要做什么? 就是要确定它的指令格式(就是指令有多少位长,哪几位表示地址,哪几位表示操作等)、类型(如堆栈型、寄存器型等分类)、操作(比如运算、数据传送啊什么的都是指令中要确定的操作)以及操作数的访问方式(一个指令要访问数据,是按其地址访问还是按内容访问等也要由指令设计来解决)。
我们知道,由多条指令构成的程序是要以二进制的形式放到存储器中的,早期的存储器很昂贵,因此导致指令设计者尽量增强一条指令的复杂性以减少程序的长度。还用微程序(就是保存在专用的存储器中的一小段程序,运行时只要用一条指令来启动它就可用来代替好多条指令) 来改进代码密度。这样的设计倾向形成了一种传统的指令设计风格,即认为计算机系统性能的提高主要依靠增加指令复杂性及其功能来获取。这就是称为复杂指令系统(CISC)的设计风格。我们现在用的PC机多是用这种设计风格的指令系统,比如MMX多媒体扩展指令等,都是增加进去的指令,是复杂指令。
后来,通过测试,这种不断增加指令复杂度的办法并不能使系统性能得到很大提高,反倒使指令系统实现更困难和费时。所以在70年代中期又出现了另一种称为"简化指令系统(RISC)"的设计风格。它的基本思想是,简单的指令能执行得更快以及指令系统只需由使且频率高的指令组成。(插话)
指令系统在设计时,应特别注意的是如何能使编译系统高效、简易地将源程序翻译成目标代码。这就是指令系统的设计原则。为了达到这个目的,在设计时应注意:正交性、规整性、可扩充性、对称性。(请对照课本加以理解)
二、指令系统集结构的分类(识记)
前面我们知道了指令系统的设计要确定它的指令格式、类型、操作及对操作数的访问方式。现在就提到了分类:
一般地,指令系统集结构分类主要是依据在CPU中以何种存储方式来存放操作数。
我们知到,CPU在进行数据计算时,总是要先把数据取到某种寄存器中才能开始。而这寄存器的类型有堆栈型、累加器型和通用寄存器型三种。相应地,使用哪种存储方式来存放操作数的,就把指令系统集结构分成堆栈型、累加器型和通用寄存器型三类。它们是有区别的,堆栈型结构中,操作数总是被默认存放在栈顶,累加器结构中,操作数总是被默认存放在累加器中;而在通用寄存器中,所有的操作数都必须被说明是存放在哪一个寄存器或存储器的哪个单元中。
所有的计算机都可按上述分类标准进行归类。但有的机器可能是某些类型的混合,如intel的8086处理器便是通用寄存器结构和累加器结构的混合。
三种类型的比较:
其中通用寄存器指令系统又可进一步分为:寄存器-寄存器、寄存器-存储器以及存储器-存储器三类。在RISC机中,只可能存在寄存器-寄存器类型。(寄存器是在计算机内部的存储小容量数据的装置,尤指数据可以同时存储和运算的装置)请注意它们的优缺点,第一种是具有最好的指令密度,但是访存速度慢。第三种方式则简单,但程序代码较长。第二种取中。
三、操作数访问(寻址)方式(识记)
指令中对操作数的访问方式,按访问手段可分为两大类:常用的是按地址访问,另一类是按内容访问方式。
计算机中的两个地址概念一个是逻辑地址、一个是物理地址,前者为虚,后者是实,一般所讨论的寻址方式是指逻辑地址的寻址方式。
地址的编址,通常有三种不同方式:(1)按各种部件分类编址;(2)统一编址;(3)隐式编址
对存储器这一存储部位编址(领会),绝大多数计算机将字节作为最小访问单位(注意,1字节=8位。1字=4字节。)这里我们要弄清什么是"大端排序"和"小端排序".比如要访问一个字(32位4字节)的时候,要求一次写入4个字节的数据,而存储器最小访问单位是1个字节,那么就需要把这"字"分成4段存入4个单元中。如果确定把这个"字"的最低有效位的字节(最右边的一段)是存储器地址末位为"0"中的内容,最高有效位的字节(最左边的一段)是地址末位为3的内容,则我们称之为小端排序(即访问字的最低有效位(小端)地址是按0、4……等顺序排列的);反之若将字的最高有效位的字节放在"0"、"4"等地址中,则称之为大端排序。
访问方式可按面向对象和寻址方式来区分:前者可分为面向寄存器、面向存储器、面向堆栈的访问方式。后者可分为如下寻址方式:(了解一下即可)
立即数 指令中所带的操作数内容即是一个可用的数绝对方式 指令中给出一个地址,访问该地址得到操作数寄存器方式 访问某个寄存器中给出的地址,由地址访问到操作数寄存器间接访问某个寄存器,由这个寄存器中的内容找到另一寄存器,由给出的地址取得操作数存储器间接访问存储器中某单元,得到另一地址,再访问到该地址取得操作数自增/自减将某寄存器中的数加上或减去操作操作数的字节数,找到地址变址方式 由寄存器中的数加上变址量得到地址…… ……
在CISC计算机中,使用频率最高的是带偏移的寄存器寻址方式,其次是直接量寻址,再就是寄存器间接寻址。在RISC机中,只选择那些使用频率高的寻址方式,如相对于寄存器寻址或PC的偏移寻址、立即数寻址以及基址加变址寻址等。
按内容访问方式时,并不提供要访问的存储单元地址,而是给出要访问的内容(很像是查询)。因此存储器的结构形式要作相应变化。为了加快访问速度,必须采用并行方式,相应的存储器就称为联想存储器。请对照课本第49页,对联想存储器的基本结构和其访问方法进行理解和领会。
实用的联想存储器,一般除有按内容访问能力外,还有按地址访问能力。
四、指令格式及其优化(简单应用)
指令一般由两部分组成:一部分是操作码,另一部分是操作地址码。当操作数地址为隐式时(如堆栈的操作,默认为栈顶),后一部分则不是必须的。根据指令地址码部分中显式指明的地址个数,则可形成零地址、单地址、二地址、三地址及四地址指令。
我们说的确定指令格式主要就是选择指令字中的操作码长度和地址数。指令字的长度有定长和变长两种。
我们着重要讨论的问题是指令格式的优化问题,优化就是以较少的格式,以尽可能短的码长来实现各种指令编码。
指令字包括操作码和地址码,所以对这两部分都采取优化措施。
1、操作码的优化。这要用到霍夫曼压缩的概念。霍夫曼压缩法是一种频率相关的编码方法,即出现频率高的字符编码短,频率低的字符编码长,这样可以缩短平均码长。我们要掌握的是用霍夫曼树实现霍夫曼编码。其方法很简单:
根据所给的各种指令使用频率,把它们从小到大依次排好作为叶结点(相同的频率可任取一个排在前),然后把最小的两个结点值(频率)相加,形成一个新结点,以这个结点的值与其他的叶结点值比较大小,仍旧取最小的两个结点值合并产生新结点,直到最终合并为一个根(通常这个值是1或100)。简单地记为:
从小到大排序,
最小两个合并,
重复上述过程,
只剩一个结束。
编码时,从根结点开始向下,凡左边分支都编为"1",右边分支都编为"0"(也可取反),则从根结点到叶结点的一条路径上的编码组合就是该指令的霍夫曼编码。(请仔细观察图4.12中的霍夫曼树)注意,霍夫曼树不是唯一的(因为相同的频率可以任取一个在前,且编码时又可任取左1或左0),但所得的平均码长应是一样的。由于霍夫曼编码得到的码长很不规整,所以有时候要采用霍夫曼扩展编码,就是在霍夫曼码的基础上对码长加以限制(取几个确定的长度如2位、4位等),对编码作适当改变。
平均码长应该容易计算吧,这也是要用到的。
2、地址码的优化。上面我们学了操作码的优化,但是一条指令码还包括地址码。两者合理安排才能使指令格式得到优化。示意如下:
由于操作码优化后是变长的编码,如果整条指令是定长的,那么使地址码的宽度应随不同指令变化,以配合操作码形成定长指令;也可以通过改变指令字中的地址数和地址码的长度,以使单地址及多址都可以在一条指令中使用;如果操作码和地址码之外还有空余的码位,则设法用来存放立即操作数或常数。
当今的RISC机指令系统中,全都是用定字长指令格式。
五、两种不同的指令系统设计风格 CISC和RISC
这两种风格应作比较深入的领会,并要识记一些内容。
CISC(复杂指令集计算机)以VAX-11/780为代表,70年代后的各种微机如我们用的intel80x86均是这种风格的计算机。
CISC设计风格的主要特点是:
(1)指令系统复杂;费时(2)绝大多数指令需要多个机器周期方可执行完毕;自由主义(3)各种指令都可访问存储器;地方主义(4)采用微程序控制;小金库(5)有专用寄存器;低效率(6)难以用优化编译器生成高效的目标代码程序。 复杂
这哪里是特点,分明是一大堆缺点嘛,RISC机的特点就是把它们"取反",凡是 CISC是这样的,它就不是这样的:
(1)简化指令系统;省时(2)除了LOAD/STORE指令外,所有指令都在一个时钟周期内执行完毕;集体主义(3)除了LOAD/STORE指令外,其余指令只与寄存器打交道;搞活流通(4)绝大部分采用硬联线控制,不用或少用微程序实现;查封小金库(5)使用较多的通用寄存器,一般至少有32个,绝没有专用寄存器;高效率(6)采用优化编译技术,生成高效的目标代码程序。 简化
RISC与CISC技术两者的主要区别在于设计思想上的差别,RISC的设计思想是;将那些不是最频繁使用的功能(指令)由软件来加以实现,这样就可以优化硬件,并可使其执行得更快。在第一章中我们学过计算机系统的设计的准则,第一个准则就是:只加速使用频率高的部件。RISC的设计思想与此完全吻合。
下面我们学习RISC技术中所采用的特殊方法:
1、采用较大量的寄存器,采用窗口重叠寄存器技术。
窗口重叠技术:在RISC结构中,为了减少过程调用中保存现场和建立新现场,以及返回时恢复现场等辅助操作,通常将所有寄存器分成若干个组,称为寄存器窗口。每组中有若干个寄存器,每当有过程调用时,就分配一个未被使用的寄存器窗口,这样就可减少保存和恢复现场的开销。此外在每个寄存器窗口中,又分成大小固定的高区、本地和低区三个区段。其中本地区用来存放局部变量,高区在被调用时用来保存调用过程送来的参数,而在返回主调用过程时,存放返回结果。而低区在调用时存放欲送往被调用过程的参数,而在被调用过程返回时用来存放返回结果。在使用时,每一对调用和被调用过程的寄存器窗口各自的低区和高区相互重叠。一旦发生过程调用或返回,在控制由一个窗口转换到另一窗口时,这些参数就通过两个窗口间的公共寄存器区自动的被传送而不需要再用额外的传送时间。 (可参照教材进行理解)。
2、采用优化延迟转移技术
优化延迟转移技术:即是使转移指令在准备将控制转向目标指令的同时,执行紧随在转移指令之后的那条指令,也就是是在将转移指令后延迟槽内的指令执行完毕后,才发生真正的转移(不论转移是否成功),这种优化技术可在保证程序正确执行的同时又可避免延迟转移中损失的一个机器周期时间。
3、采用比较转移指令
比较-转移指令:在RISC机中,把比较和转移(在CISC机中需用两条指令完成的功能)合并成一条指令。该指令将直接对两个对象(寄存器-寄存器或存储器-立即数)进行相等或不等比较,然后根据比较结果判别是否进行转移。这样就可省去一条指令,并不受条件码的约束。
4、采用优化编译技术
优化编译技术:在编译时就可发现可能出现的阻塞情况,由编译器通过重排指令执行序列来消除可能出现的阻塞情况,当无法消除时就填入相应的空操作,因此不需要硬件的互锁流水支持。
以上的特殊技术并中是每一种RISC机都采用的,在RISC机中有两个比较典型的代表,一个是加州大学伯克莱分校的RISC-I、II机的思路,侧重系统结构的支持,采用由大量寄存器组成的寄存器堆及窗口重叠技术。另一个是遵循斯坦福大学的MIPS机器思路,侧重采用编译的支持,采用优化编译技术,。
CISC和RISC两种设计风格的比较,其实就是说RISC优点,简单地说就是快、省、可靠、易实现、好优化。
关于RISC的两种代表机型的指令系统实例,要对照它们的指令系统中指令数、指令格式、寻址方式及采用的特殊技术来进行比较。