第二章 指令系统
本章内容 2.1 数据表示 2.2 寻址技术 2.1.1浮点数表示 2.1.2 自定义数据表示 2.2.1 编址方式 2.2.2 寻址方式 2.2.3 程序在主存中的定位方法
本章内容 2.3 指令格式的设计和优化 2.4 指令系统的改进 习题二 2.3.1 指令操作码的优化 2.3.2 地址码的优化表示 2.3 指令格式的设计和优化 2.3.1 指令操作码的优化 2.3.2 地址码的优化表示 2.3.3 指令格式设计实例 2.4 指令系统的改进 2.4.1 RISC与CISC的概述 2.4.2 RISC指令系统实例 习题二
第二章 指令系统 指令系统是硬件和软件之间的接口,硬件设计人员采用各种技术来实现指令系统;软件设计人员基于指令系统来编制相应的系统软件,这些软件用来填补硬件实现的指令系统与各种编程语言之间的语义差距。指令系统是计算机系统的软硬件功能分配的界面,指令系统设计是计算机系统结构设计的核心,它对计算机系统的性能有直接影响。 指令系统实际上定义了硬件和编译器之间的接口,它是一种硬件和编译器都能理解的语言。一方面,指令系统表明了一台计算机具有哪些硬件功能,是硬件逻辑设计的基础。因此,在指令系统层,应该定义一套在当前和将来技术条件下能够高效率实现的指令集,从而使高效率的设计可用于今后的若干代计算机中。另一方面,指令系统应该为编译器提供明确的编译目标,使编译结果具有规律性和完整性。
第二章 指令系统 指令系统是硬件和软件之间的接口,硬件设计人员采用各种技术来实现指令系统;软件设计人员基于指令系统来编制相应的系统软件,这些软件用来填补硬件实现的指令系统与各种编程语言之间的语义差距。指令系统是计算机系统的软硬件功能分配的界面,指令系统设计是计算机系统结构设计的核心,它对计算机系统的性能有直接影响。 指令系统实际上定义了硬件和编译器之间的接口,它是一种硬件和编译器都能理解的语言。一方面,指令系统表明了一台计算机具有哪些硬件功能,是硬件逻辑设计的基础。因此,在指令系统层,应该定义一套在当前和将来技术条件下能够高效率实现的指令集,从而使高效率的设计可用于今后的若干代计算机中。另一方面,指令系统应该为编译器提供明确的编译目标,使编译结果具有规律性和完整性。
第二章 指令系统 本章主要介绍与指令系统直接有关的数据表示,然后阐述指令系统优化设计的方法和技术,最后讨论指令系统发展中的CISC(复杂指令系统计算机)和RISC(精简指令系统计算机)两种设计思想,并介绍典型RISC处理器MIPS R4000和SPARC的指令系统。
2.1 数据表示 数据表示是数据类型中最常用的、相对比较简单的、易于硬件实现的那些数据类型。相对较复杂的数据类型,如表、树、队列、链表等则是由软件来处理,它们是数据结构研究的对象。数据结构和数据表示是软、硬件的交界面。系统结构设计在软、硬件功能分配时,应考虑在机器中设置哪些数据表示,以便对应用中的数据结构有高的实现效率,这是以花费适当的硬件为代价的。 由于基本的数据表示在其他课程已有详细阐述,本节介绍主要更深入地介绍浮点数表示涉及到的一些问题,以及自定义数据表示。
2.1.1浮点数表示 现代的大部分计算机都引入了浮点数据表示,典型的长度有32位和64位。浮点数表示的关键问题是,在数据字长确定的情况下,能设计出一种具有最佳表示范围、表示精度和表示效率的浮点数表示方式。 1. 浮点数的表示范围 在机器中,典型的浮点数机器字格式如图2-1所示。
2.1.1浮点数表示 图2-1中,浮点数机器字代码由两部分组成:阶码部分和尾数部分。阶码部分包含了阶符和阶码值两部分。尾数部分包括数符和尾数值。浮点数的值可表示为: 其中
2.1.1浮点数表示 浮点数表示需要确定以下6个参数: ① 尾数的基rm 尾数的值可以采用原码或补码表示,数值可以采用小数或整数表示。 ③ 尾数长度n 尾数占用的二进制位数称为尾数长度,不包括符号位。
2.1.1浮点数表示 尾数的基为rm,尾数长度为n可表示的rm进制数的位数为 。当尾数采用二进制即rm=2时,尾数长度n就是 ;如果尾数采用十六进制,则需要4位二进制数表示1位十六进制数,这时十六进制尾数的实际位数为 =n/4 ④ 阶码的基re 阶码一般采用二进制表示,即阶码的基re=2。 ⑤ 阶码的值e 阶码的值e一般采用移码或补码表示,数值采用整数表示。 ⑥ 阶码长度q 由于阶码采用二进制,因此,阶码长度q的值就是阶码部分的二进制数位数。注意q不包括阶码符号位。
2.1.1浮点数表示 从式(2-1)可以看出,浮点数的表示范围与尾数的基值rm有关,也与阶码位数q和尾数位数p以及采用的机器数表示形式有关。 由于机器字长的限制,任何一种浮点数的表示范围和可表示的浮点数个数是有限的,浮点数只能表示出数轴上分散于正、负两个区间上的部分离散值,如图2-2所示。
2.1.1浮点数表示 在浮点数表示的正数区间:规格化浮点数的最大正数值Nmax由尾数的最大正数值与阶码的最大正数值组合而成;规格化浮点数的最小正数值Nmin由尾数的最小正数值与阶码的最小负数值组合而成。在浮点数表示的负数区间:规格化浮点数的最大负数值(-Nmax)由尾数最大负数值与阶码最小负数值组合而成;规格化浮点数的最小负数值(-Nmin)由尾数的最小负数值与阶码的最大正数值组合而成。
2.1.1浮点数表示 在尾数采用原码、纯小数,阶码采用移码、整数的浮点数表示方式中,规格化浮点数的表示范围N正和N负为:
2.1.1浮点数表示 当尾数采用补码、纯小数,阶码采用移码、整数的浮点数表示方式中,规格化浮点数在正数区间完全相同,但是负数区间有区别,N负的表示范围为: 从以上公式可以看出,浮点数的表示范围与尾数的基值rm有关,也与阶码位数q和尾数位数p以及采用的机器数表示形式有关。但是,影响浮点数表示范围的主要因素是尾数基值rm和阶码位数q。
2.1.1浮点数表示 例2-1 浮点数长度32位,数符1位和阶符1位,阶码长度q=6,尾数长度n=24,尾数和阶码采用二进制,即rm= re=2。尾数采用原码、纯小数,阶码采用移码、整数,其规格化浮点数表示范围为: 即
2.1.1浮点数表示 例2-2 浮点数长度32位,数符1位和阶符1位,阶码长度q=6,尾数长度n=24,尾数采用十六进制和阶码采用二进制,即rm=16,re=2。尾数采用原码、纯小数,阶码采用移码、整数,给出其规格化浮点数表示范围。 解:由于尾数采用十六进制,24位二进制表示6位十六进制数,故浮点数表示范围为: 即
2.1.1浮点数表示 从上述两个例子可以看出,当浮点数阶码尾数的二进制位数、码制、小数点位置都相同时,则浮点数表示范围由基值rm决定,基值rm越大表示范围越大;但是,基值rm越大,浮点数在数轴上的分布越稀。 2.规格化浮点数的表数个数 由于字长限制,浮点数表示方式所能表示的浮点数个数是有限的、不连续的。可表示的规格化浮点数的个数应该是可表示的阶码的个数与可表示的尾数的个数的乘积。 如果阶码的基re=2,则q位长的阶码可表示的阶码的个数为2q个。
2.1.1浮点数表示 尾数的基为rm,n位长的尾数可表示的rm进制数的位数为 ,每个rm进制数的数位均可以有 共有rm个取值,所以,尾数的总个数为 ,但应去掉小数点后第1个 进制数位是0的那些非规格数。显然,非规格化尾数的个数占了全部尾数总个数的 的比例。因此,可表示的浮点数规格化数的总个数就为 。 由此推出可表示的规格化浮点数的个数为:
2.1.1浮点数表示 可以推出, 越大,在与 =2的浮点数相重叠的范围内,所表示数的个数要少得多,即数的密度分布会更稀。 3.规格化浮点数的表数精度 浮点数表示方式所能表示的浮点数个数是不连续的、有限的,只能表示出实数中很少的一部分,是实数的一个子集,称为浮点数集。 浮点数集的表数误差指的是浮点数集中两个最接近的浮点数之间的误差。在浮点运算中,会出现运算中间结果或最后结果的尾数不在浮点集中的情况(不是溢出),这时必须用最接近这个结果的浮点数表示。如,浮点加法运算过程中,对阶操作需要对一个浮点数进行右规时,就要对尾数的最低位进行舍入,通常采用四舍五入来确定最低位的值,这时就产生了误差。
2.1.1浮点数表示 表数误差也称为表数精度。规格化浮点数的表数精度直接与尾数基rm的取值和rm进制的尾数位数 有关。规格化浮点数运算中,如果需要对尾数的最低位进行处理,通常采用四舍五入的规则,因此,可以认为表数误差是尾数的最后一位的值的一半。由此可以得出规格化浮点数的表数精度为: (2-3)
2.1.1浮点数表示 根据式(2-3),可以得出例2-1和例2-2中两种不同尾数基值浮点数的表数精度分别为: 比较以上的两个浮点数的表数精度,可以看出尾数基值rm=16时,其表数精度与rm=2相比将损失23倍。显然,当浮点数尾数的二进制位数长度相同时,尾数基值rm为2具有最高的表数精度。
2.1.1浮点数表示 4.浮点数机器字的格式设计 定义一种浮点数机器字的格式需要确定浮点数表示的6个参数,具体原则如下: ① 确定尾数m的数制和码制。主要从运算简单、表数直观等方面来考虑,目前多数机器尾数m采用小数、原码表示。尾数m采用原码表示,虽然加减法比采用补码表示复杂,但乘除法要简单得多。 ② 确定阶码e的数制和码制。目前一般机器阶码e都采用整数、移码表示。阶码e采用移码表示的主要原因是使浮点数零与机器零一致,而且移码的大小直接反映了阶码真值的大小,这便于两个浮点数的阶码比较。由于阶码主要是用来扩大浮点数的示数范围的,因此,阶码e必须用整数表示。
2.1.1浮点数表示 ③确定尾数的基rm。前面的讨论表明在浮点数机器字长一定的情况下,取rm=2时,浮点数有最高的表数精度。目前多数机器尾数基值rm 取2。 ④ 确定阶码的基re。在一般通用计算机中,都取re=2。 ⑤ 在浮点数表示方式中,尾数长度n主要影响表数精度,阶码长度q主要影响示数范围。可根据要求的示数范围和表数精度确定n和q的值。 按照目前多数实际机器的情况,假设:浮点数尾数m用原码、小数表示,阶码e用移码、整数表示,尾数基值rm=2,阶码基值re=2。要求浮点数表示范围不小于N(N为可表示的最大正数),表数精度不低于 ,确定q和n的值的方法如下。
2.1.1浮点数表示 根据浮点数表示范围的要求,可得下式: 解这个不等式: 得到阶码长度q为: (2-4)
2.1.1浮点数表示 根据浮点数表示精度要求,可得下式: 故得出尾数长度n为: (2-5) 由(2-4)和(2-5)两个不等式得出的阶码长度q和尾数长度n,再加上一个尾数符号位mf和一个阶码符号位ef,就组成了一种满足以上假设浮点数表示范围和表数精度的浮点数机器字格式。一般为了使浮点数机器字字长满足整数边界的要求,还需要适当调整q和n的值。
2.1.1浮点数表示 例2-3 设浮点数尾数m用原码、小数表示,阶码e用移码、整数表示,尾数基值rm=2,阶码基值re=2。要求规格化浮点数的表示范围N为 ,要求浮点数表数精度不低于 ,试设计一种浮点数的格式。 根据浮点数表示范围的要求,用式(2-4)计算阶码的长度q:
2.1.1浮点数表示 考虑到要满足整数边界,可取阶码长度 位。 根据浮点数表数精度要求,用式(2-5)计算尾数长度n:
2.1.1浮点数表示 此例中,阶码长度q=7位,尾数长度n=54位,再加上1位尾数符号位和1位阶码符号位,则浮点数机器字字长为2+q+n=63位,距离机器字字长的整数边界要求还差1位。这一位可以加到尾数长度n上用以提高表数精度,也可以加到阶码长度q上用以扩大示数范围。如果将这1位加到尾数长度上,则设计的64位浮点数机器字格式如图2-3所示。
2.1.2自定义数据表示 在数据表示上,高级语言与机器语言一直存在语义差距。高级语言中,在引用数据之前必须用类型说明语句定义数据类型,其运算符不反映数据类型,是通用的。如在C语言程序中,有以下语句: int i,j float x,y i=i+j x=x+y
2.1.2自定义数据表示 由此可见,i、j是整型数据,x、y是实型数据, 运算符“+”可用于整型也可用于实型数据相加。然而,一般的机器语言程序则完全不同,指令中是由操作码定义操作数据的类型。如浮点数加法机器指令: 以上指令中,操作码是浮点加,指定对操作数X和Y进行浮点加法运算,无论X和Y是否是浮点数,都是按浮点数对待。因此,编译时就需要把高级语言程序中的数据类型说明语句和运算符转换成机器语言中不同类型指令的操作码,并要验证指令中操作数的类型是否与运算符所要求的一致,若不一致,还需用进行处理,从而增加了编译程序的复杂性。 浮点加 X Y
2.1.2自定义数据表示 为了在数据表示上缩小高级语言与机器语言的语义差距,有人提出在机器语言级实现自定义数据表示,即由数据本身定义自己的类型,同时也简化了指令系统和编译器。 自定义数据表示主要有带标志符的数据表示和数据描述符数据表示。 1. 带标志符的数据表示 带标志符的数据表示是指在数据中采用若干位来表示数据的类型。
2.1.2自定义数据表示 如早期的B7500大型机中,每个数据用三位标志符来区分8种数据类型,如图2-4所示。 标志符虽然主要用于指明数据类型,也可用于指明所用信息类型。二十世纪70年代的R-2计算机中,采用带标志符的数据表示的数据字格式如图2-5所示。
2.1.2自定义数据表示 图2-5中, 共有10位标志,2位功能位用于区别数据是操作数、指令、地址还是控制字。2位陷阱位用于软件定义4种捕捉方式,为程序员对程序进行跟踪控制提供方便。1位读写位用于指定数据是只读的还是可读可写的。4位类型位可在功能位定义的基础上进一步定义数据的类型。如果功能位定义了数据类型是操作数,则类型位进一步定义操作数是二进制数、十进制数、定点数、浮点数、字符串、单精度、双精度等。如果功能位定义了数据类型是地址,则类型位进一步定义地址的寻址方式等。最后1位标志位是奇偶校验位。
2.1.2自定义数据表示 标志符数据表示缩小了高级语言和机器语言语义差距,但是数据字因增设标志符,会增加程序所占的主存空间,而且按标志符确定数据属性及判断操作数之间是否相容等操作,会降低单条指令的执行速度。 2.数据描述符数据表示 对于一组具有相同类型而且是连续存放的数据,如向量、矩阵和多维数组,没有必要让每个数据都带有相同的标志符,因此,可以采用数据描述符。
2.1.2自定义数据表示 数据描述符与标志符的主要区别是:标志符只作用于一个数据,而描述符要作用于一组数据。因此,标志符通常与数值一起存放在同一个数据单元中,而描述符一般单独占用一个存储单元。描述符在描述一组数据的属性中,还包括整个数据块的访问地址、长度及其他特征或信息。 B6700计算机的描述符如图2-6所示,前三位为“000”,表示该字为数据;前三位为“101”,表示该字为数据描述符。如果该字是数据描述符,则进一步用8位标志位描述数据特性。如果描述的是整块数据时,“地址”字段用于指明首元素的地址,“长度”字段用于指明块内的元素个数。
2.1.2自定义数据表示 (a) 数据描述符 (b) 数据 图2-6 B6700机中数据描述符表示
2.1.2自定义数据表示 a00 a01 a02 a03 A = a10 a11 a12 a13 a20 a21 a22 a23
2.1.2自定义数据表示 一级描述符的“长度”位为3,指向有3个元素的二级描述符的首址;每个二级描述符的“长度”位都为4,分别指向对应的有4个元素的数据。实际上,两级描述符构成了一颗双层树。类似的,用三层结构的描述符就可以描述三维数组。 图2-7中,二维阵列A是一条指令的一个操作数,指令中的一个地址X指向描述A阵列的一级描述符,OP表示操作码。
2.1.2自定义数据表示 图2-7 用数据描述符表示一个3×4二维阵列
2.2寻址技术 从指令系统层来看,程序所处理的数据通常存放在主存储器、寄存器、堆栈、I/O接口中,寻址技术就是指如何从这些存储部件中获得数据的技术。寻址技术主要讨论存储部件的编址方式、寻址方式和定位方式。 在“计算机组成原理”课程中对指令的各种寻址方式有详细的介绍,在本节我们更注重于分析和比较它们的特点。
2.2.1编址方式 要访问存放在主存储器、寄存器、堆栈、I/O接口中的数据,必须对这些存储部件的空间进行编址。编址方式主要涉及编址单位和编址空间。 1. 编址单位 存储空间常用的编址单位有:字编址、字节编址和位编址。 字编址是指每个编址单位与访问的数据存储单元(如读/写一次寄存器、主存单元)相一致,即每个编址单元的二进制位数与一次访问存储部件所获的二进制位数是相同的。这种方式硬件实现容易,但是不便于处理非数值(如字符)信息。目前仍然有一些面数值计算的机器采用这种编址方式。
2.2.1编址方式 字节编址是指以1个字节作为编址单位。这是目前大多数通用计算机采用的编址方式,以适应非数值计算的应用需求。 位编址是指以1个二进制位作为编址单位。在很多单片机中,有的存储器区域和控制寄存器可以按位编址,同时它们也按字节编址,对位进行访问或操作是用位操作指令完成。单片机主要用于嵌入式系统的硬件控制,使用位操作指令可以很方便地对I/O端口的位进行处理。 多数机器按字节编址,但是通常主存储器的字长是4个字节以上,而且多数机器允许按字节、单字、双字访问存储器,因此编址单位与访问存储器的信息宽度不一致,从而产生数据如何在存储器中存放的问题。
2.2.1编址方式 如某台机器,按字节编址,数据有字节(8位)、半字(双字节)、单字(4字节)和双字(8字节)不同宽度。主存数据宽度64位,即一个存储周期可访问8个字节。采用按字节编址,大于字节宽度的数据是用该数据的首字节地址来寻址的。一种存放数据的方法是,在主存中允许数据从任意字节地址单元存放,如图2-8(a)所示,这种方法很容易出现一个数据跨主存宽度边界存储的情况;对于跨界存放的数据,即使数据宽度小于或等于主存宽度,也需要两个存储周期才能访问到,导致访问速度显著下降。
2.2.1编址方式 另一种数据存放方法是,要求数据在主存中存放的地址必须是该数据宽度(字节数)的整数倍,即双字地址的最低3个二进制位必须为000,单字地址最低2位必须为00,半字地址最低1位必须为0,如图2-8(b)所示。这种存放方法也称为按整数边界存储方式,它可以使访问任意宽度的数据都只用一个存储周期。虽然浪费了一些存储空间,但是速度比上一种方法有显著提高。
图2-8 数据在主存中的存放方式 (a)数据按任意字节地址存放
图2-8 数据在主存中的存放方式 (b)数据按整数边界存放
2.2.1编址方式 2. 编址空间的组织 计算机中需要编址的存储部件主要有:通用寄存器、主存储器和I/O接口。它们的编址空间可以有以下3种组织方式。 (1)三个地址空间 由于通用寄存器、主存储器和I/O接口的工作速度和容量等性能差别较大,很多机器中对这3个地址空间进行独立编址。也就是说,每个地址空间都从0开始编地址码。 CPU中的通用寄存器数量有限,访问速度很快,其容量比主存储器小得多,所需要的地址码长度短。一般只有单一的直接寻址方式。
主存储器的容量大,所需要的地址码长度很长。采用的寻址方式最复杂,一般有间接寻址和变址寻址等多种寻址方式,以避免在指令中直接表示主存单元的地址码。 I/O接口中的寄存器的数量一般比通用寄存器多,其地址码长度介于寄存器和主存之间,因此多采用直接寻址方式,也有机器采用寄存器间址方式。 三个地址空间独立编址,由于每个地址空间都从0开始编码,因此三个空间会有重叠,但是指令的操作码和寻址方式会明确指出所访问的是哪个地址空间。访问I/O地址空间则需要设置专用的I/O指令。如Intel 80x86系列就采用三个地址空间独立编址。
(2)二个地址空间 CPU的通用寄存器独立编址;I/O接口寄存器和主存储器统一编址,统一编址空间的高端地址一般用于I/O接口寄存器地址。采用二个地址空间的组织方式,访问主存的指令就能访问I/O寄存器,可以减少指令条数,但存在的问题是主存的地址空间会减小。如VAX-11系列机就采用二个地址空间的组织方式。 (3)一个地址空间 所有数据存储单位统一编址,地址空间的低端地址是CPU的通用寄存器地址,高端地址是I/O接口寄存器地址。在单片机中,片内存储器容量不大,一般采用一个地址空间,以减少指令种数。 计算机中的一些专用寄存器或寄存器堆,如预取指令和数据的缓冲器,是不需要编址的。Cache存储器映射的是相联的主存内容,因此不需要编址。在堆栈型计算机中,数据的存取完全按照先进后出的方式进行,其存储部件是不需要编址的。
2.2.2 寻址方式 一条指令包括操作码和地址码,指令的功能就是根据操作码对地址码提供的操作数完成指定的操作。指令中以什么方式提供操作数或操作数地址,称为寻址方式。 CPU根据指令约定的寻址方式对地址字段的有关信息作出解释,以找到操作数。每种机器的指令系统都有一套自己的寻址方式。不同计算机的寻址方式的分类和名称并不统一,但大多数可以归结为以下几种类型。 (1)立即寻址 操作数在指令中,在取出指令的同时也就取出了可以立即使用的操作数,这种寻址方式称为立即寻址方式。它不需要访问任何地址空间,指令执行速度很快。缺点是指令字中的立即数长度有限,可用于为程序提供精度要求不高的整型常数。
(2)寄存器寻址 操作数存放在寄存器中,在指令中给出寄存器地址(编号),执行指令时,根据该寄存器号就可以从中获取操作数。寄存器寻址方式有两个重要的优点: a. 从CPU的寄存器中读取操作数要比访问主存快得多,因而在CPU中设置足够的寄存器,以尽可能多地在寄存器之间进行运算操作,已成为提高工作速度的重要措施之一。 b. 由于寄存器数远小于主存单元数,所以指令中寄存器编号字段所占位数也就大大少于主存地址码所需位数。 寄存器寻址方式是RISC计算机中主要和基本的寻址方式,尤其是其运算类指令的操作数和结果都采用这种寻址方式。它也是多数CISC计算机采用的寻址方式。
(3)主存寻址 主存寻址方式主要有直接寻址方式、间址寻址方式和变址类寻址方式。 ⅰ. 直接寻址方式 直接寻址方式要求指令中直接给出操作数或结果所在主存单元的地址。这种寻址方式简单易于实现;但是主存容量很大使其地址码很长,而指令字中分配给地址码的位数有限,特别在二地址指令和三地址指令中,这个矛盾更加突出。此外,直接寻址的地址码是指令的一部分,不能随程序需要而动态改变,不能满足程序循环和程序在主存中浮动的需要。
ⅱ. 间接寻址方式 存储器间接寻址方式是在指令中给出操作数地址的地址,一般需要通过二次访问主存才能获得操作数。这种寻址方式通过多层读取来提供地址的可变性,增加了编程的灵活性;但指令中需要的地址码长,且访存次数的增加减慢了指令执行速度。 寄存器间接寻址方式通过在寄存器中存放操作数地址,指令执行时,先访问寄存器号指定的寄存器并从中获得主存单元地址,然后再访问该主存单元地址指定的主存单元获得操作数。这种寻址方式能用短的地址码对相当大的主存空间寻址,寻址过程只需一次访存,因此广泛用于大多数计算机中。而且,程序采用这种寻址方式可以通过修改间址寄存器内容访问不同的主存单元,为编程提供了方便。
ⅲ. 变址类寻址方式 变址寻址方式由指令给出变址寄存器编号和一个形式地址(也称为地址偏移量),指令执行时,将变址寄存器内容与形式地址相加,得到操作数地址,按此地址访问主存单元就得到操作数。其典型用法是将指令中不能修改的形式地址作为基准地址,而将变址寄存器内容作为修改量。如某个数组存放在一段连续的主存区间中,首址为B,可让B作为指令中的形式地址,而变址寄存器中存放修改量,即所需访问单元与首址单元之间的距离。通过修改变址寄存器内容,该指令本身不需任何修改,就可以访问该数组的任何一个元素。显然,变址寻址能够方便灵活地对数组、表格、链表等数据结构进行访问与处理。这种寻址方式通过地址计算使地址灵活可变,为大多数机器采用。
基址寻址方式是将指令给出的基址寄存器内容和一个形式地址相加得到操作数地址。其形成操作数地址的方法与变址相同,也可以认为是变址的一种特殊形式,但是二者的应用目的不同。 基址寻址的一种典型应用是程序重定位。目标程序是在操作系统管理下调入主存运行的,因此用户在用高级语言编程时并不知道这段程序将被安排在主存的哪一段区域,所以用户编程时使用的是一种与实际主存地址无关的逻辑地址,将来运行时再自动转换为操作系统分配给它的实际主存地址(物理地址),这类问题称为程序重定位。在多道程序方式中更需要解决程序重定位问题。显然,采用基址寻址方式能够较好地解决这个问题。在实现程序重定位时,由操作系统给用户程序分配一个基地址,并将它装入基址寄存器,在程序执行时就可以自动形成实际的主存地址。
另一种典型应用是扩展有限字长指令的寻址空间。由基址寄存器提供全字长的地址码,足以指向主存的任何区间,运行时基址寄存器装入某个主存区间的首址,或是程序段的首址。而指令中的形式地址位数较少,只需给出主存单元相对于首址的偏移量即可。例如主存容量16 MB,基址寄存器24位,基址可以指向全部地址空间;指令中相应地址字段16位,其中2位用于指定4个基址寄存器之一,14位形式地址给出偏移量,可以访问某个16 KB的空间。由于程序运行的局部性,在某段时间内运行在一个有限区间之内,上述办法能够满足实际需要,通过修改基址可以移向另一区间。
需要指出,在实际机器中,变址/基址的应用方式可以有不同变化。有的机器中既有基址寻址也有变址寻址;有的机器中,基址寻址与变址寻址实际上是合二为一的;也有两种寻址的合成即基址变址寻址方式,需要进行两次变址计算才能得到操作数的地址。 变址寻址的另一种特殊形式是相对寻址,这时变址寄存器就是程序计数器。程序计数器指示的是下条指令地址,而指令中的偏移量指出的是操作数地址与程序计数器内容之间的相对距离。当指令地址变化时,由于其偏移量不变,使得操作数与指令在可用的存储区内一起移动,所以仍能保证程序的正确执行。相对寻址的指令在程序重定位时,指令地址码是不需要修改的,因此多数机器的转移类指令常采用相对寻址方式。
(4)堆栈寻址 操作数存放在堆栈中,指令隐含约定由堆栈指针SP寄存器提供堆栈栈顶单元地址,进行读出或写入。堆栈中的数据只能先进后出,因此对堆栈空间寻址无需指明地址。如果堆栈操作指令的另一个操作数涉及寄存器或主存空间,则需要在指令中给出相应的寻址方式。堆栈寻址可省去有的地址字段,节省了程序空间,存储效率高。 堆栈“后进先出”的特点非常适合子程序多重嵌套、递归调用、多重中断等方式。此外堆栈还适合于逆波兰式计算场合。堆栈寻址几乎是现代计算机都采用的寻址方式。
一台机器的指令系统可以采用多种寻址方式,那么在指令中如何区分它们呢?常见的方法有两种:一种方法是由操作码决定其寻址方式,即由操作码含义隐含约定采用何种寻址方式;另一种方法是在指令中设置寻址方式字段,由字段不同的编码组合来指定操作数的寻址方式。
2.2.3 程序在主存中的定位方法 在多数计算机中,编译器在对一个源程序或源程序段进行编译时,是不能确定程序在主存中的实际位置。因此,编译后的目标程序通常是从零地址开始分配地址空间,这种地址称为逻辑地址。逻辑地址的集合称为逻辑地址空间。计算机中的主存储器,是一维线性编址的,这种地址称为主存物理地址,其地址的集合称为主存物理空间。 对于多道程序,各目标程序的逻辑地址空间与物理地址空间是不一致的。当程序装入主存时,就需要进行逻辑地址空间到物理地址空间的转换,即对程序进行重定位。
一种定位方法是要求对程序中那些需要修改地址的指令和数据加上某种标识,在程序运行之前,由专门的装入程序一次将目标程序的带标识指令和数据的逻辑地址变换成物理地址,程序一旦装入主存其物理地址不再改变,这种定位技术称为静态重定位。这种定位方式允许程序每次运行前装入到主存不同的物理地址空间中,但是程序运行时位置不能改变。如图2-9所示,当目标程序A装入主存从a地址开始的物理空间中时,为了正确运行程序,指令的地址码应必须根据不同的寻址方式作相应的变换。如用直接寻址、间接寻址和变址寻址访存时都应将指令中的逻辑地址加一个a值,而对立即数和相对地址,则不加a值。
图2-9 静态定位方式
静态定位方式允许程序在每次运行前装入到主存不同的物理地址空间中,但是程序运行时位置不能再改变,故主存利用率低。如果程序需要的容量超过分配给它的物理空间,就必须采用覆盖结构。此外,多个用户不能共享存放在主存中的同一个程序。而程序的动态定位方式则可以避免这些问题。 程序动态定位方式是指,程序在装入主存时不修改指令的地址码,而是在程序执行时,通过硬件支持的基址寻址方式将操作数的逻辑地址转换为主存的物理地址。
如图2-10所示,将目标程序A在主存中的起始地址a存入对应的基址寄存器中,程序执行时,由地址加法器将指令操作数的逻辑地址加上基址寄存器中程序的起始地址,就形成了操作数的物理地址。实际上,并不是所有指令的地址码都需要修改,如立即寻址和相对寻址是不需要修改的,为此需要在指令中标识本指令的主存地址码是否需要加上基址。
图2-10 动态定位方式
动态定位方式允许为一个程序分配不连续的主存空间,并且也允许多个程序共享存放在主存中的同一个程序段,有效地提高了主存的利用率。它还可以支持虚拟存储器,从而大大扩展了逻辑地址空间。但实现动态定位方式需要有硬件支持且实现存储管理的软件算法较复杂。
2.3 指令格式的设计和优化 设计者在选择指令格式时,必须考虑许多因素。包括扩展新指令和利用在指令系统的使用周期中出现的新技术都是相当重要的。具体的设计原则主要有三条。 首先,一般情况下,短指令要优于长指令。由n条32位指令组成的程序所占的内存空间只是n条64位指令组成的程序的一半。内存带宽(内存每秒钟能够读写多少位)一直是系统的主要瓶颈之一,减小指令长度可以有效地缓解这一瓶颈。由于现代处理器具有在一个时钟周期内并行取多条指令的能力,较短的指令长度意味着可以更快地处理。但是,使指令长度达到最小,可能会使译码和重叠执行变得困难,因此,在考虑最小化指令长度时,必须兼顾考虑译码和指令执行所需要的时间。
2.3 指令格式的设计和优化 第二条原则是在指令格式中必须有足够的空间来表示所有的操作类型,还要考虑留下富余的空间给以后的扩展指令使用。如一台有2n种操作的计算机,它的指令长度必须大于n。 第三条原则是关于地址码中位的数量。例如,设计一台使用8位字符、具有232个字符大小主存的计算机,一种方法是使用字节作为内存的基本单元,按字节编址可访问的地址空间是4 GB,字节编址使得对字符的操作相对容易实现,较短的地址也意味着指令长度相对较短,可以节约存储空间和取指时间;另一种方法是使用32位字作为内存的基本单元,按字编址可访问的地址空间是16GB,大大高于前一种方法,但是对字符的操作需要程序从字中分离它们,且指令长度也会相对较长。
2.3 指令格式的设计和优化 本节先描述与分析指令操作码的三种编码方式和地址码的优化,然后讨论典型的CISC处理器Pentium II与RISC处理器SPARC的指令格式。
2.3.1 指令操作码的优化 一条指令是由操作码和地址码两部分组成的。指令操作码的优化,就是指如何用最短的二进制位数来表示指令的操作信息,使程序中指令的平均操作码长度最短。 操作码的编码方式主要有三种:定长操作码、哈夫曼(Huffman)编码和扩展编码。 1. 定长操作码 定长编码是指所有指令的操作码长度都是相等的。如果需要编码的操作码有n个,那么,定长操作码的位数最少需要 位。例如用指令字中第一个字节(8位)表示操作码。这种方式有利于简化硬件设计和减少指令译码时间,但是浪费了信息量。 很多机器如IBM公司的大、中型机和RISC(精简指令系统计算机)体系结构都采用这种编码方法。
2.3.1 指令操作码的优化 2. 哈夫曼编码 哈夫曼(Huffman)编码法的基本思想是,当各种事件发生的概率不均等时,对发生概率最高的事件用最短的编码来表示,而对出现概率较低的事件用较长的编码来表示,这样可以使事件编码的平均位数缩短,从而减少处理时间。哈夫曼编码法可以用于信息压缩的场合,如存储空间的压缩和时间的压缩。 使用哈夫曼编码对操作码进行优化表示,就需要知道每种指令在程序中出现的概率(使用频度),这是通过对大量已有的典型程序进行统计后得出的。
2.3.1 指令操作码的优化 编码优化的程度用平均码长来评价,平均码长定义为: (2-6) 其中, 是表示第i种操作码在程序中的出现概率或使用频度,共有n种操作码; 是第i种操作码的编码长度。 也可以用位冗余量来衡量编码优化的程度,位冗余量为 (2-7) 其中 (2-8)
2.3.1 指令操作码的优化 H称为信息熵(Entropy),表示用二进制编码表示n个码点时,理论上的最短平均编码长度。因此,对实际编码的平均码长l,都有 ,故有0<R<1。
2.3.1 指令操作码的优化 例2-4 假设某模型机共有n=10种不同的指令,经统计各指令在程序中的使用频度如表2-1所示。若操作码用定长码表示需要 =4位。 表2-1 某模型机指令使用频度举例 指令 使用频度(pi) 指 令 I1 0.25 I6 0.08 I2 0.20 I7 0.05 I3 0.15 I8 0.04 I4 0.10 I9 0.03 I5 I10 0.02
2.3.1 指令操作码的优化 根据式(2-8)计算操作码的最短平均编码长度为: 这表明模型机10种指令的操作码平均只需2.96位即可。如果用4位定长码表示,l=4,根据式(2-7)计算信息冗余量为:
2.3.1 指令操作码的优化 下面对此例使用哈夫曼编码,如图2-11所示。首先利用哈夫曼算法,构造哈夫曼树。将所有10条指令的使用频度从小到大排序构成一个结点集,每次从结点集中选择频度最小的两个结点合并成频度为这两个频度之和的父结点,若结点集不为空集,就将生成的新结点放到结点集中,继续从这个新的结点集中选择出2个频度最小的结点生成其父结点,直至结点集成为一个空集,就生成了一棵哈夫曼树。从根节点开始,对每个结点的两个分支分别用“0”和“1”标识。
图2-11 哈夫曼树举例
2.3.1 指令操作码的优化 如果要得到指令Ii的操作码编码,则根据图2-11的哈夫曼树,从根结点到Ii叶结点的路径上,将沿线所经过的0或1代码依次组合起来就形成了Ii指令的哈夫曼编码,如表2-2左部分所示。
表2-2 操作码哈夫曼编码和扩展操作码编码 指令 频度pi 操作码OP使用哈夫曼编码 OP长度li 2-4扩展操作码编码 I1 0.25 表2-2 操作码哈夫曼编码和扩展操作码编码 指令 频度pi 操作码OP使用哈夫曼编码 OP长度li 2-4扩展操作码编码 I1 0.25 0 0 2 I2 0.20 1 0 0 1 I3 0.15 0 1 0 3 1 0 0 0 4 I4 0.10 1 1 0 1 0 0 1 I5 0.08 0 1 1 0 1 0 1 0 I6 1 1 1 0 1 0 1 1 I7 0.05 0 1 1 1 0 5 1 1 0 0 I8 0.04 0 1 1 1 1 1 1 0 1 I9 0.03 1 1 1 1 0 I10 0.02 1 1 1 1 1 1 1 1 1
2.3.1 指令操作码的优化 根据式(2-6)计算操作码哈夫曼编码的平均码长为: 平均码长2.99位,非常接近于H。这种哈夫曼编码的信息冗余量为: 与4位定长码的26%信息冗余量相比要小得多。
2.3.1 指令操作码的优化 需要指出的是哈夫曼编码并非是惟一的。只要将哈夫曼树各分支的“0”与“1”互换,就可以得到一组新的编码。如果存在多个相同的最小频度,由于频度合并的次序不同,会导致生成不同的哈夫曼树,得到的编码也不相同。但是,计算的哈夫曼编码平均码长l是惟一的,而且是可用二进制位编码平均码长最短的编码,因此哈夫曼编码是最优化的编码。
2.3.1 指令操作码的优化 3. 操作码扩展编码 哈夫曼编码具有最优化的平均码长,信息冗余量也接近理想值。但是,哈夫曼编码形成的操作码一般不规整,码长种类多,上例中10种指令就有4种码长,不利于实现硬件译码和软件编译。 为此,实际机器中采用将定长操作码与哈夫曼编码结合形成的一种编码方式,称为操作码扩展编码。这种编码方式的操作码长度不是定长的,但只限于几种码长,较规整。编码时,仍利用高概率的用短码、低概率的用长码表示的哈夫曼压缩思想。具体编码规则是,根据要求确定编码的几种长度,然后从最短码开始,一种长度的编码通常要剩下一个或多个码点用作扩展标志,为后续较长的编码使用。与哈夫曼编码类似,扩展操作码中的短码不能是长码的前缀。
2.3.1 指令操作码的优化 对于例2-4中的10条指令,如果采用扩展操作码编码,则可以有多种方法。采用2-4扩展操作码编码如表2-1右部分所示。将使用频度高的I1、I2用两位操作码的00、01表示,剩下的二个码点10、11作为扩展为4位编码的标志。 根据式(2-6)计算这种扩展操作码编码的平均码长为:
2.3.1 指令操作码的优化 这种表示法的平均长度和信息冗余量,虽比哈夹曼编码的大,但比定长4位码小得多,而且编码较规整,是一种实际可用的优化编码。 为了便于硬件分级译码,一般采用等长扩展,如4-8-12扩展法表示操作码位数按4位、8位和12位,每级加长4位扩展。类似还有3-6-9扩展法等。实际机器中,也有根据需要采用每级扩展位数不等的不等长扩展法。 在4-8-12等长扩展法中,如果选择的扩展标志不同就会有不同的扩展方法。如15/15/15法和8/64/512法。 如图2-12所示,15/15/15法是在4位的16个码点中,保留1个码点作为扩展标志,在8位和12位码长也是如此。8/64/512法是在4位的16个码点中,保留8个码点作为扩展标志;在8位的128个码点中保留64个码点作扩展标志;在12位的1024个码点中保留512个码点作扩展标志。
图2-12 操作码等长扩展编码法
2.3.1 指令操作码的优化 指令使用频度pi的分布可以作为选择哪种编码的依据。例如,某机器中有15种指令的pi值都比较大,还有15种次之,其余pi值很小,则适合选择15/15/15法;如果只有8种指令的pi值较大另外64种指令的pi值次之,则适合采用8/64/512法。而实际机器中可采用更为灵活的扩展方式,如PDP-11机器的指令操作码长度有4位、7位、8位、10位、12位、13位和16位。
2.3.2 地址码的优化表示 指令由操作码和地址码组成。由于下一条指令地址由程序计数器给出,因此地址码只需要给出操作数和结果的地址。地址码长度主要取决于地址码个数、寻址方式、存储设备(通用寄存器、主存和堆栈等)的编址方式和寻址空间大小等。 1. 地址码个数 指令的地址码个数常见的有三个地址、二个地址、一个地址及零地址。 (1)三地址指令格式为: OP A1 A2 A3
2.3.2 地址码的优化表示 OP表示操作码;A1、A2、A3分别表示操作数1的地址、操作数2的地址、结果存放地址,A1、A2和A3可以是主存单元地址或寄存器地址。 这种格式可以使操作后两个操作数均不被破坏,可供再次使用,间接减少了程序的长度。如典型的RISC处理器都设置有三地址指令。 (2)二地址指令格式为: OP A1 A2
2.3.2 地址码的优化表示 由A2提供源操作数源地址;由A1提供目的操作数地址,在运算后不再保留,该地址改为存放运算结果,只是A1 或A2应尽量采用通用寄存器,以减少访存次数。这种格式减少了指令给出的显地址数,可以缩短指令长度。Intel 80x86主要采用这种指令格式。 (3)一地址指令格式为: OP A
2.3.2 地址码的优化表示 一地址指令有两种常见的形态,根据操作码含义确定它属于哪一种。 2.3.2 地址码的优化表示 一地址指令有两种常见的形态,根据操作码含义确定它属于哪一种。 ① 只有目的操作数的单操作数指令。指令中只给出一个目的地址A,A既是操作数的地址,又是操作结果的存放地址。 ② 隐含约定目的地址的双操作数指令。在某些机器中,双操作数指令也可采用一地址指令格式。源操作数按指令给出的源地址A读取,另一个操作数(目的操作数)隐含在CPU的累加器AC中,运算结果也将存放在AC中。如Intel 8x86的乘法、除法指令就采用该格式。 可见,一地址指令不仅可用来处理单操作数运算,也可用来处理双操作数运算,这是使用隐地址以简化地址结构的典型例子。
2.3.2 地址码的优化表示 OP 4)零地址指令格式为: 指令中只有操作码,不含操作数。这种指令有两种可能: 2.3.2 地址码的优化表示 4)零地址指令格式为: 指令中只有操作码,不含操作数。这种指令有两种可能: ① 不需要操作数的指令。例如空操作指令、停机指令等。 ② 所需操作数是隐含指定的。如计算机中对堆栈操作的运算指令,所需的操作数事先约定在堆栈中,由堆栈指针SP隐含指出,操作结果仍送回堆栈中。又如Intel 80x86的串操作处理指令,其操作数是隐含指定的。 OP
2.3.2 地址码的优化表示 从上述讨论可知,指令格式中采用隐含指定操作数地址(即隐地址)能够有效地减少地址数,实际上缩短了指令码的长度。 2.3.2 地址码的优化表示 从上述讨论可知,指令格式中采用隐含指定操作数地址(即隐地址)能够有效地减少地址数,实际上缩短了指令码的长度。 上述几种指令格式只是一般情况,并非每台计算机都具有。例如在Intel 80x86的指令系统中,指令地址格式有零地址、一地址和二地址3种形式。三地址地址指令具有功能强、便于编程等特点,因此多为指令字长较长的大型机所用。又如RISC处理器以三地址指令为主,也设置少量二地址、一地址和零地址指令。 在设计指令格式时,可以将操作码扩展编码与不同地址个数组配使用,以平衡指令的长度。下面通过一个例子来说明。
2.3.2 地址码的优化表示 例2-5 设某机器的指令长度是16位,而其中操作数地址长度为4位。这种情况对于具有16个寄存器(寄存器地址4位)而且算术运算都在寄存器中进行的计算机来说,是非常合适的。一种设计方案是每条指令具有4位的操作码和3个地址,这样共有16条三地址的指令,其格式为: 15 12 11 8 7 4 3 0 OP A1 A2 A3
2.3.2 地址码的优化表示 但是如果共需要15条三地址指令、14条二地址指令、31条单地址指令和16条零地址指令。则一种扩展方法如图2-13所示。
图2-13 一种16指令长度的操作码扩展方法
2.3.2 地址码的优化表示 上述例子表明,可以通过将最短的操作码分配给需要最多的位来定义其他信息的指令,使各指令的长度保持相等。但是,从优化操作码的角度,同时又必须考虑给常用的指令分配短的操作码,给不常用的指令分配长的操作码来使平均指令长度达到最短。在实际机器中,也可以采用变长指令,只是要求指令长度是字节或字的倍数,因此,指令格式的设计必须综合权衡多种因素。 2. 缩短地址码的方法 当前大多数计算机系统都采用虚拟存储器系统,为程序提供更大的地址空间,这就要求指令中的访存操作数地址是一个逻辑地址(虚拟地址),其长度一般远超过实际主存的所需地址长度。因此,需要考虑如何用较短的地址码来表示一个较大的逻辑地址空间。下面讨论几种常用的缩短地址码的方法。
2.3.2 地址码的优化表示 现代处理机内部通常都设置一定量的寄存器,但数目有限,其地址码较短。因此,无论是采用寄存器直接寻址,还是寄存器间接寻址都可以有效地缩短地址码长度。例如,某机器有32个寄存器,每个寄存器长度是32位,一个寄存器地址只需要5位,如果采用寄存器间址,5位地址码就可以间接给出32位的存储器逻辑地址。 采用基址或变址寻址方式缩短地址码长度。由基址寄存器提供全字长的地址码,足以指向整个逻辑地址空间,运行时可以用基址寄存器装入某个主存区间或是程序段的首址,指令中的位移量只是相对于首址的偏移量,位移量可以比较短。例如Intel 80x86实模式的位移量通常为8位或16位。
2.3.2 地址码的优化表示 采用存储器间接寻址方式缩短地址长度。例如,主存储器按字节编址,将主存低1KB区域专门用来存放地址,如果逻辑地址需要32位,则用连续4个字节单元就可以存放32位地址,即1KB主存空间可以存放256个地址,在指令中用8位长度就可以表示32位地址。
2.3.3 指令格式设计实例 在设计指令格式时,需要考虑指令的长度是采用固定的长度,还是采用可变长度。由于不同指令表示的信息量差异很大,可变长度指令就可以满足这样的需求,但是读取变长指令的时间会延长,而且指令越复杂执行时间也越长,实现也就更复杂。反之,指令长度固定,格式简单,则读取与执行时间短,实现相对容易。 目前多数复杂指令系统集计算机CISC都采用可变长度指令,如Intel 80x86系列。而精简指令系统计算机RISC则一般采用固定长度指令,如SPARC、MIPS。下面以典型的CISC的处理器Pentium II与RISC处理器SPARC为例讨论其指令格式。
2.3.3 指令格式设计实例 1. Pentium II指令格式 2.3.3 指令格式设计实例 1. Pentium II指令格式 PentiumⅡ的指令格式相当复杂。这首先是因为要与Intel 80x86兼容,而80x86的指令格式就比较复杂。再者是因为PentiumⅡ对地址和数据的32位扩展,以及增加了寻址方式的灵活性。 在下面介绍的PentiumⅡ指令的各个组成部分中,只有操作码字段是必须出现的,其他字段都是可选的。图2-14给出了PentiumⅡ的指令格式,最多具有6个变长域。指令前缀一般根据需要选用,并放在指令前面。在Pentium机器码程序中,大部分指令并无前缀,它们使用默认的条件进行操作。
图2-14 PentiumⅡ指令格式
2.3.3 指令格式设计实例 PentiumⅡ指令地址格式包括二地、一地址址和零地址3种形式。如果双操作数指令的一个操作数在内存中,那么另一个就不能在内存中。 在早期的80x86体系结构中,虽然也使用了前缀字节来修改某些指令,但是所有指令的操作码长度都是一个字节的长度。前缀字节作为额外的操作码附加在指令的最前面用于改变指令的操作。然而,在80x86体系结构发展的过程中,所有的操作码已经用完,因此操作码0xFF作为出口码(escape code),以表示本条指令的操作码是两字节的。 Pentium II的操作码通常需要完全译码后才能确定执行哪一类操作,同样,指令的长度也只有在操作码译码后才能知道,也就是译码后才能确定下一条指令的起始地址。这就使实现更高的性能如多条指令重叠或同时执行变得更为困难,这也是可变长度指令都存在的问题。
2.3.3 指令格式设计实例 操作码之后的是模式字节,模式字节及下一个字节SIB定义寻址方式。模式字节分为3个字段,它们是MOD(2位)、REG(3位)和RM(3位)。REG定义一个寄存器操作数,另一个操作数由MOD和R/M组合在一起(5位)指定。5位可以区分32种可能性,它们是8个寄存器操作数和24种存储器数据寻址方式。其中的一种(MOD/RM=00/100)要求使用SIB字节,设置SIB字节是为了保持向下兼容的同时增加原来没有想到的新特性。 SIB字节专门为比例变址寻址而设置。它由3个字段组成:INDEX(3位)定义变址寄存器。SCALE(2位)定义比例因子,BASE(3位)定义基址寄存器。存储器地址的计算方法是,变址寄存器的内容乘以比例因子,再加上基址寄存器的内容。
2.3.3 指令格式设计实例 如果MOD/RM定义的寻址方式中需要位移量,则由DISP字段给出。位移量可以是8位、l6位或32位。如果不需要位移量,则该字段不出现在指令格式中。 IMME字段给出立即数指令中的立即数,它可以是8位、16位或32位。 2. SPARC指令格式 SPARC(Scalable Processor Architecture)是指由Sun公司定义的一种RISC处理器结构。Sun已经研制了自己的SPARC处理器,而且也许可其他厂商生产SPARC兼容机。
2.3.3 指令格式设计实例 SPARC所有指令的长度固定为32位。如图2-15所示,最高两位操作码(op)定义指令格式,基本指令格式只有3种。格式l专为CALL指令而设,格式2为SETHI(置高位)和BRANCH(转移)指令而设。常用的算术逻辑操作指令、LOAD/STORE指令及其他指令均使用格式3。第2个操作码op2用于区分BRANCH、SETH等指令。第3个操作码op3是定义指令操作的,每条指令只定义一个单独的操作。opc是协处理机指令操作码,opf是浮点处理机指令操作码。
图2-15 最初的SPARC指令格式
2.3.3 指令格式设计实例 如图2-15中的指令格式3,大多数指令的第1个源操作数rs1是寄存器操作数;第2个可能是寄存器rs2,也可能是立即数simm13;而目的地址一般均是寄存器rd(除了store和转移指令外)。整数算术逻辑运算指令是将rs1与rs2 的内容(或simm13)按操作码op3规定的操作运算后把结果送往rd ,其功能可以描述为: 当格式第13位i=0时,(rs1)op3(rs2)→rd; 当i=1时,(rs1)op3 simm13→rd。 LOAD指令将存储器中的数据送往rd中,而STORE指令将rd中的数据送往存储器中。存储器地址的计算方法如下(寄存器间接寻址方式): 当i=0时,存储器地址=(rs1)+(rs2); 当i=1时,存储器地址=(rs1)+simm13。
2.3.3 指令格式设计实例 由于指令长度是32位,因此不能在指令中包括32位常量。SETHI指令只能设置22位常量,而把剩下的10位留给其他指令去实现。 非预取的条件转移指令使用格式2,由cond字段决定测试哪种条件。a位用于延迟转移控制,当a=0时,跟在转移指令下面的指令总是被执行;当a=1时,只在条件转移指令转移成功时,跟在转移指令下面的指令才被执行。 格式1用于执行过程调CALL指令。这条指令很特别,其操作码只有两位,其余30位都用于定义地址。 图2-15是最初的SPARC指
2.3.3 指令格式设计实例 格式是通过把一些位分成不同的字段得到的。例如,最初的转移指令使用格式2,有22位的偏移量。当加入分支预取指令时,22位中的3位被移作他用,其中1位用于预测(预测/不预测),其他两位用于定义使用的条件码位集合,只剩下19位的偏移量。 SPARC的指令格式、指令类型和寻址方式相对简单,可以认为是RISC体系结构的代表。
2.4 指令系统的改进 精简指令系统计算机RISC是20世纪80年代提出的一种新的设计思想。目前市场上很多处理机都采用了RISC体系结构,如SUN公司的SPARC、SuperSPARC、UtraSPARC,SGI公司的R4000、RS000、R10000,IBM公司的Power、PowerPC,Intel公司的80860、80960,DEC公司的Alpha,Motorola公司的88100等。此外,一些典型的复杂指令系统计算机CISC的处理机设计时也吸收一些RISC的设计思想,如Intel公司的80486和Pentium系列。 本节先介绍CISC的概述、RISC的发展及特点,然后以两个典型的RISC处理器MIPS R4000与SPARC为例,讨论其指令系统。
2.4.1 RISC与CISC的概述 1.CISC与RISC 随着超大规模集成电路VLSI技术的迅速发展,使计算机系统中的硬件成本不断下降,而软件成本却在不断上升。因此,人们热衷于在指令系统中增加更多的指令和复杂的指令,以适应不同应用领域的需要,并考虑尽量缩短指令系统与高级语言之间的语义差异,以便于高级语言的编译和降低软件成本。 另外,为了维护系列机的软件兼容性,也使指令系统变得越来越庞大。在系列机中,为了使老用户在软件上的投资不受损失,新机型必须继承老机器指令系统中的全部指令,这种情况使同一系列计算机的指令系统越来越复杂。例如DEC公司的VAX-11/780有303条指令、18种寻址方式。一般来说,人们在计算机设计方面的传统想法和做法是:进一步增强原有指令的功能以及设置更为复杂的新指令取代原先由软件子程序完成的功能,实现软件功能的硬化,从而使机器指令系统日益庞大和复杂,按这种传统方法设计的计算机系统称为复杂指令系统计算机(Complex Instruction Set Computer),简称CISC。
2.4.1 RISC与CISC的概述 指令系统很复杂、功能很强并不一定能提高机器的速度,CISC中采用很多复杂的寻址方式,为了计算有效地址需花费一定的时间;有的指令需要多次访问主存储器,所以执行速度会降低。 复杂指令系统的实现需要复杂的控制器来支持,VLSI生产工艺要求规整性,而CISC处理器中,为了实现大量的复杂指令,控制逻辑极不规整,增加了VLSI设计与生产的难度。在微处理器芯片中,复杂的控制器占据的面积大,限制了其他部件的硬件资源。 系列机为实现兼容,其控制部件多用微程序控制方式来实现,以便于指令系统的扩展。但微程序控制部件执行一条机器指令通常需要几个微周期,因此降低了指令的执行速度。 为了提高指令的执行速度,CISC中常采用流水线技术。但由于存在很多问题,例如指令系统采用变字长指令、不同指令争用共同资源以及转移指令等,使流水线的效率不高。
2.4.1 RISC与CISC的概述 在CISC系统上运行大量程序获得的统计分析结果表明,各种指令的使用频率相差悬殊,最常用的是一些比较简单的指令,仅占指令总数的20%,但在程序中出现的频率却占80%;而有80%左右的指令很少使用,它们的使用量约占整个程序的20%。这个分析结果使得人们怀疑CISC是否有必要设置实现大量的复杂指令。 综上所述,传统的CISC设计思想不利于提高计算机的速度。而且复杂的指令系统必然增加硬件实现的复杂性,从而使计算机的研制周期长、投资大。因此人们开始研究传统指令系统的合理性问题。 1975年,IBM公司提出了精简指令系统的想法。后来美国加利福尼亚大学伯克利分校的RISC I和RISC II、斯坦福大学的MIPS机的研制成功,为精简指令系统计算机RISC(Reduced Instruction Set Computer)的诞生与发展奠定了重要基础。
2.4.1 RISC与CISC的概述 2.RISC的特点 精简指令系统计算机RISC的着眼点并不是简单地放在简化指令系统上,而是通过简化指令使计算机的结构更简单合理,从而提高处理速度,其精髓是减少指令执行的平均周期数CPI。 RISC是一种计算机系统结构的设计思想,直到现在都还没有一个确切的定义。下面给出RISC设计思想的一些主要特点。 (1)大多数指令在一个周期内完成 指令系统中的大多数指令是执行一些简单的和基本的功能,这些指令可较快地在单周期内执行完毕,从而使指令的译码和解释的开销减少。RISC为了更好的实现这个特点,必须采用流水线结构。 (2)采用LOAD/STORE结构 由于访问主存储器指令花费时间较长,因此在指令系统中尽量减少访问主存指令,而只保留不能再减掉的LOAD(取数)与STORE(存数)两种访存指令。由于其他大多数指令都不能访存,这些指令所需要的操作数都来自通用寄存器,运算结果也暂存于通用寄存器,因此容易实现在单周期内完成。
2.4.1 RISC与CISC的概述 (3)较少的指令数和寻址方式 选取使用频率高的一些简单指令,以及少量能有效支持操作系统、高级语言实现及其他功能的指令,减少指令条数。选用简单的寻址方式,以寄存器寻址及寄存器相关的寻址为主。从而简化控制部件,有利于减少指令的执行周期数。 (4)固定的指令格式 指令长度、格式固定,可简化指令的译码逻辑,并有利于提高流水线的执行效率。为了便于编译的优化,常采用三地址指令格式。 (5)面向寄存器的结构 为减少访问主存储器,CPU内应设较多的通用寄存器。一般RISC计算机中至少有32个通用寄存器,可以存放程序的全局变量和局部变量。
2.4.1 RISC与CISC的概述 (6)硬布线控制逻辑 由于指令系统的精简,控制部件可由组合逻辑实现,不用或少用微程序控制,这样可使控制部件的速度大大提高。此外,芯片上的控制部件所占面积也大为减小,可腾出更多空间放寄存器组、Cache等部件,这就减少了部件间的连线延迟,又进一步提高了操作速度。 (7)注重编译的优化 RISC指令系统的简化,必然使编译生成的代码长度增长。但通过编译优化技术,将编译初步生成的代码重新组织,即对目标指令代码的执行次序进行重新排序,以充分发挥内部操作的并行性,从而进一步提高流水线的执行效率。虽然编译优化技术使编译时间拉长,但这种代价的结果是使程序的执行时间缩短。而且程序的编译工作只需一次,编译后生成的优化执行代码却可以高效率地执行多次。因此这个代价是值得的。
2.4.1 RISC与CISC的概述 根据RISC的设计思想,1981年加州大学伯克利分校的David Patterson等人研制出了32位RISC I微处理器。其指令系统的31种指令包括:12种算术逻辑指令,8种访问存储器的指令,7种程序控制指令和4种其他指令。指令字长度固定为32位,以三地址指令为主,有少量二地址和一地址指令,可识别三种数据类型。只有变址寻址和相对寻址两种寻址方式。按字节编址,只有LOAD/STORE指令可以访问存储器,其他指令的操作都在通用寄存器之间进行。时钟频率为8MHz,所有指令都在一个机器周期(500ns)完成。CPU设置了78个通用寄存器,将它们分为多个寄存器窗口提供给相应过程使用,即采用重叠寄存器窗口技术。
2.4.1 RISC与CISC的概述 由于RISC I控制器部分只占CPU面积的6%,因此才有较大的面积用于安排较多的寄存器。而当时属于CISC型微处理器的MC68000的控制器部分占芯片面积的50%,Z8000的控制器部分占芯片面积的53%,因此,它们的芯片上无法安排数量众多的寄存器,只能更多地访问存储器。而且RISC I该处理器的设计和布线错误分比Z 8000和MC 68000少3~4倍,研制周期比Z 8000和MC 68000少4~6倍,其速度却比MC 68000和Z 8000的快3~4倍,有些功能还超过了PDP-11/70和VAX-11/780小型机。
2.4.1 RISC与CISC的概述 随着计算机技术的不断发展,RISC的设计思想也有了一些发展变化,更强调所设计的指令系统支持流水线的高效率执行,并支持编译器生成优化代码。 RISC为了使流水线高效率执行,应具有以下特征: ⑴简单而统一的指令格式,加快指令译码; ⑵大部分指令在单周期完成; ⑶只有LOAD/STORE指令能够访问主存; ⑷简单的寻址方式; ⑸采用延迟转移技术; ⑹ LOAD延迟技术。
2.4.1 RISC与CISC的概述 RISC为了支持编译器生成优化代码,应具有以下特征: ⑴三地址指令格式; ⑵较多的寄存器; ⑶对称的指令格式。 RISC技术存在的问题是编译后生成的目标代码较长,占据了较多的存储器空间。然而,RAM芯片的集成度不断提高,成本不断下降,存储空间的增加不成为重要的问题。RISC设计思想不仅为RISC机所采用,一些传统的CISC机的设计也吸取了RISC的特点。如Intel 80486设计时就吸取了RISC中的思想,其中很重要的一点就是注重常用指令的执行效率,减少常用指令执行所需的周期数。
2.4.1 RISC与CISC的概述 3. RISC与CISC的典型参数比较 在1.5.2节曾介绍了一个程序执行时所花费的CPU时间可以表示为:CPU时间=IC×CPI×时钟周期 其中,IC是指令条数,CPI是每条指令所需的平均时钟周期数。 表2-3对典型CISC与RISC的3个参数IC、CPI和时钟周期进行了比较。 类型 指令条数 IC 指令平均周期数CPI 时钟周期 CISC 1 2~15 33~5ns RISC 1.3~1.4 1.1~1.4 10~2ns
2.4.1 RISC与CISC的概述 对表2-3给出的3个参数进行如下的分析比较: (1)程序所执行的总指令条数IC RISC选择的是比较简单且使用频度较高的一些指令,CISC中的一条复杂指令所完成的功能在RISC中可能要用几条指令才能实现。在对同一个源程序分别编译后所生成的目标代码,RISC的目标代码要比CISC的目标代码长。但是,由于CISC中复杂指令在程序中的比例很少,其程序目标代码中的绝大多数指令都是同RISC一样的简单指令,因此,大量的统计结果表明,RISC的程序目标代码的总指令条数IC只比CISC的IC多30%~40%。
2.4.1 RISC与CISC的概述 (2)指令平均周期数CPI 由于CISC的指令一般是用微程序解释执行,一条指令需要几个时钟周期才能完成,一些复杂指令则需要十几个、几十个周期才能完成。统计表明,大多数CISC指令执行平均周期数CPI为4~6个周期。RISC的大多数指令都是单周期执行的,只有少数复杂指令和访存操作的LOAD和STORE指令需要多个周期,所以RISC的CPI略大于1。例如,SUN公司的SPARC处理机的CPI为1.3~1.4,SGI公司的MIPS处理机的CPI为1.1~1.2。 (3)时钟周期 由于RISC的指令条数较少、指令格式较规整及寻址方式简单,加速了指令译码和易于硬布线逻辑实现,因此,RISC的CPU时钟周期一般小于CISC的时钟周期。目前使用中的RISC处理机的工作主频一般高于CISC处理机。
2.4.1 RISC与CISC的概述 由表2.3可以估算出RISC的程序执行速度要比CISC快3倍左右。其中的关键在于RISC的指令平均时钟周期数CPI减小了。CPI减少是RISC结构各个特点共同支持的结果,指令格式、寻址方式、指令条数和指令功能的简化,大大降低了硬件实现的复杂性,更好地支持指令流水线高效率的执行;同时采用编译优化技术,也有助于提高流水线的效率。 在CISC中,通过增强指令系统的功能,增加了实现指令系统的硬件的复杂程度,但却简化了由指令系统支持的软件尤其是操作系统。虽然CISC一般采用微程序控制,影响了指令的执行速度,但可以方便支持指令系统的兼容性。
2.4.1 RISC与CISC的概述 可以说,RISC的出现是计算机系统结构发展最重要的变革之一,一方面CISC通过吸收RISC设计思想提高了传统机器的性能例如,Intel公司的80x86处理机的指令平均周期数在不断缩小,8086的CPI约为20,80286的CPI约为5.5,80386的CPI约为4,80486的CPI接近2;另一方面,RISC指令系统也开始采用一些复杂而必要的指令,使RISC计算机结构也日益复杂,部分RISC的逻辑实现采用硬联和微程序相结合,让大多数简单指令用硬联方式实现,功能较复杂的指令允许用微程序解释实现。从目前的发展趋势来看,RISC与CISC的优势互补和技术交融将会持续下去。
2.4.2 RISC指令系统实例 1. MIPS R4000指令系统 典型的RISC计算机是MIPS Technology公司推出的MIPS系列计算机。MIPS R2000、R3000和R6000微处理器芯片,具有相同的32位系统结构和指令系统。MIPS R4000与之前芯片不同,它所有内部和外部数据路径和地址、寄存器以及ALU都是64位的,当然其指令系统是保持兼容的。 64位的结构提供更大的地址空间,允许操作系统将大于1012字节的文件直接映射到虚拟存储器,方便了数据的存取。由于目前普遍使用磁盘空间达到或超过100GB,32位机器的4G地址空间变成了限制。此外,64位使得R4000能够处理更高精度的浮点数如IEEE单精度浮点数,以及能够一次处理字符串数据中的8个字符。
2.4.2 RISC指令系统实例 R4000处理器芯片成两个部分,包括CPU和存储管理协处理器。CPU结构简单,其设计思想是,尽可能使指令执行逻辑简单,留出空间用于增加提高性能的逻辑线路。 处理器设置了32个64位通用寄存器,分别表示为$0 ~ $31。$0寄存器的值固定为0,是一个特殊寄存器。因此,存放数据的寄存器只有31个。 R4000包括一个64KB的指令Cache和一个64KB的数据Cache。相对较大的Cache允许系统保持更多的程序代码和局部数据,从而减少了访存冲突和提高了指令速度。
2.4.2 RISC指令系统实例 (1)MIPS的指令格式 MIPS的指令采用32位固定长度,支持三地址指令。指令格式有3种,包括立即数型、转移型和寄存器型,如图2-16所示。MIPS的寻址方式只有3种:立即数寻址方式、寄存器寻址方式、以及基址加16位偏移量的访存寻址方式。
图2-16 MIPS的指令格式
2.4.2 RISC指令系统实例 采用寄存器型格式的指令主要是算术逻辑运算指令,其中两个源操作数寄存器号用rs与rt表示,结果寄存器号用rd表示,操作码用op表示。指令中的shift字段指定移位操作时移位位数,Function字段是扩展操作码指示ALU/Shift功能。包含立即数的运算指令采用立即数型指令格式,立即数为16位;取数指令LW(Load Word)和存数指令SW(Store Word)也采用立即数型指令格式,指令格式中的16位adress字段存放地址的偏移量;条件转移指令也是立即数型指令格式,转移地址采用相对寻址,指令格式中的16位adress字段存放相对寻址的地址偏移量。无条件转移指令采用转移型指令格式,指令中的Target字段存放26位的目标指令地址。
2.4.2 RISC指令系统实例 (2)MIPS指令集 MIPS R系列处理器的基本指令集如表2-4所示。MIPS基本指令集有8类指令,具体包括:LOAD/STORE指令、算术指令(含立即数)、算术指令(三地址,寄存器寻址)、移位指令、乘/除指令、跳转和分支指令、协处理器指令以及专门指令。所有运算操作都基于寄存器;只有LOAD/STORE指令能够访问主存储器。 R4000没有存放条件码的专用寄存器。如果一条指令产生某个条件,其相应的标志存于一个通用寄存器中。这可以避免采用专门处理条件代码的逻辑,因为它们影响流水线的执行和编译器对指令的重排序。而且,采用了处理寄存器值相关性的逻辑,以保证流水线的高效率。
表2-4 MIPS R系列基本指令集 操作码 说明 LOAD/STORE指令 SLLV 逻辑左移可变 LB 装入字节 SRLV 逻辑右移可变 LBU 装入无符号字节 SRAV 算术右移可变 LH 装入半字 乘/除指令 LHU 装入无符号半字 MULT 乘 LW 装入字 MULTU 无符号乘 LWL 装入左字 DIV 除 LWR 装入右字 DIVU 无符号除 SB 存储字节 MFHI 由HI送出 SH 存储半字 MTHI 送至HI SW 存储字 MFLO 由LO送出 SWL 存储左字 MTLO 送至LO SWR 存储右字 跳转和分支指令 算术指令(含立即数) J 跳转 ADDI 加立即数 JAL 跳转并链接 ADDIU 加无符号立即数 JR 跳转到寄存器
表2-4 MIPS R系列基本指令集 操作码 说明 SLTI 小于立即数置位 JALR 跳转并链接寄存器 SLTIU 小于无符号立即数置位 BEQ 相等分支 ANDI AND立即数 BNE 不等分支 ORI OR立即数 BLEZ 小于或等于零分支 XORI XOR立即数 BGTZ 大于零分支 LUI 装入上部立即数 BLTZ 小于零分支
表2-4 MIPS R系列基本指令集 算术指令(3地址,寄存器寻址) BGEZ 大于或等于零分支 ADD 加 BLTZAL 小于零分支并链接 ADDU 无符号加 BGEZAL 小于或等于零分支并链接 SUB 减 协处理器指令 SUBU 无符号减 LWCz 装入字以协处理器 SLT 小于置位 SWCz 存储字以协处理器 SLTU 无符号小于置位 MTCz 传送到协处理器
表2-4 MIPS R系列基本指令集 XOR 异或 CFCz 由协处理器传出控制 NOR 或非 COPz 协处理器操作 移位指令 BCzT SLL 逻辑左移 BCzF 协处理器z假分支 SRL 逻辑右移 专门指令 SRA 算术右移 SYSCALL 系统调用 BREAK 断点
表2-5 R4000附加的指令 R4000在MIPS基本指令集的基础上增加了一些附加指令,如表2-5所示。新的指令类型只增加了异常处理指令,其余的是原有类型指令的扩充。 操作码 说明 LOAD/STORE指令 异常指令 LL 装入链接的 TGE 若大于或等于自陷 SC 条件存储 TGEU 若无符号大于或等于自陷 SYNC 同步 TLT 若小于自陷 跳转和分支转移指令 TLTU 若无符号小于自陷 BEQL 等于时转移 TEQ 若等于自陷 BNEL 不等于时转移 TNE 若不等自陷 BLEZL 小于或等于零转移 TGEI 若大于或等于立即数自陷 BGTZL 大于零转移 TGEIU 若大于或等于无符号立即数自陷
表2-5 R4000附加的指令 BLTZL 小于零转移 TLTI 若小于立即数自陷 BGEZL 大于或等于零转移 TLTIU 若小于无符号立即数自陷 BLTZALL 小于零转移并链接 TEQI 若等于立即数自陷 BGEZALL 大于或等于零转移并链接 TNEI 若不等于立即数自陷 BCzTL 协处理z为真时转移 协处理器指令 BCzFL 协处理器z为假时转移 LDCz 装入双协处理器 SDCz 存储双协处理器
2.4.2 RISC指令系统实例 MIPS用硬件实现的是最简单的和最常用的存储器寻址方式。这种存储器寻址方式实际上是基址寻址,即地址是由一个存放在寄存器中的基地址与相对该基址的一个16偏移量相加获得。例如,装入字指令LW的具体使用形式如下: lw r2, 128(r3);((r3)+128)→ r2 以上指令的含义是,以寄存器r3的内容为基地址加上128(偏移量),形成存储器地址,将此地址存储单元的字内容装人寄存器r2中。 MIPS的编译器使用多条机器指令的合成来实现普通机器中的典型寻址方式。表2-6给出了三条合成指令对应的一条或几条实际指令,其中使用了lui (Load Upper Immediat)指令,这条指令将16位立即数装人寄存器高半部,低半部置为全0。
表2-6 用MIPS寻址方式合成其他寻址方式 合成指令 对应的实际指令 lw r2,<16位偏移量> lw r2,<16位偏移量>(r0) lw r2,<32位偏移量> lui r1,<偏移量的高16位> lw r2,<偏移量的低16位>(r1) lw r2,<32偏移量的低16位>(r4) addu r1,r1,r4
2.4.2 RISC指令系统实例 2. SPARC指令系统 SPARC处理器的设计借鉴了美国加州大学巴克利分校研制的RISC I机器,它的指令集和寄存器组织基本上基于RISC I。 (1)SPARC寄存器组与重叠寄存器窗口技术 RISC处理器的指令系统比较简单,CISC中的一条复杂指令,在RISC中可能要用一段简单指令组成的子过程(子程序)代码段来实现。因此,相比CISC,RISC程序中会出现更多的CALL和RETURN指令。 执行CALL指令时,必须把硬件现场(主要是程序计数器内容和处理机的程序状态字)和软件现场(主要是指子过程会改写的通用寄存器中的内容等)保存到主存中。此外,还需要调用过程(父过程)将参数传递给被调用过程(子过程)。子过程在执行RETURN指令时,要恢复现场,并把结果传送回父过程。因此,执行CALL和RETURN指令时,访问存储器的信息量很大,频繁的访存操作会大大降低系统的性能。
2.4.2 RISC指令系统实例 为了尽量减少访存操作,F. Baskett提出了重叠寄存器窗口(Overlapping Register Window)技术,并首先在RISC I上应用,SPARC也采用了这种技术。 重叠寄存器窗口的基本思想是:在处理器中设置数量较多的寄存器,并把它们划分成多个窗口。如图2-17所示,为每个过程分配一个窗口,每个窗口包括3组寄存器:参数寄存器、局部寄存器和临时寄存器,其中参数寄存器与父过程共用,用来存放父过程传送给本过程的参数,同时也存放本过程传送给父过程的计算结果;临时寄存器与子过程共用,用来存放本过程传送给子过程的参数和子过程传送给本过程的计算结果。也就是说,分配给过程的寄存器窗口是按照调用关系进行部分重叠的。
2.4.2 RISC指令系统实例 SPARC采用了重叠寄存器窗口技术。每个窗口由24个寄存器组成;总的窗口数可以从2到32个,取决于具体实现。图2-15说明了8个窗口的实现,总共使用了136个物理寄存器。物理寄存器R0~R7,是所有过程共用的全局(Global)寄存器。
2.4.2 RISC指令系统实例 为每个过程分配一个窗口,即可寻址逻辑寄存器R0~R31,窗口分为3组寄存器,每组8个寄存器。逻辑寄存器R24~R31标记为输入,与父过程共用;逻辑寄存器R8~R15标记为输出,与子过程共用。这两组寄存器与其他窗口重叠。逻辑寄存器R16~R23标记为局部的,是本过程使用的局部寄存器,既不与其他过程共用,也不与其他窗口重叠。如图2-18所示。
图2-18 SPARC 寄存器窗口布局和三个过程
2.4.2 RISC指令系统实例 采用重叠寄存器窗口技术,对程序来说任何时刻都只能看见和寻址32个逻辑寄存器,尽管实际的物理寄存器不止32个。寄存器窗口重叠是为了在过程之间有效地传递参数,要实现窗口重叠则需重新命名寄存器,针对图2-15中的过程B,原有的父过程A输出寄存器R8到R15仍然可见,但是它们现在的名字是输入寄存器R24到R31,也就是说寄存器的名字被重新命名了。然而,8个全局寄存器R0~R7是不会变的,也就是说,它们对所有的寄存器窗口都是相同的。
2.4.2 RISC指令系统实例 如图2-19所示,给出了8个窗口即从窗口W0到W7构成的环形窗口。SPARC允许把最后一个过程的输出寄存器组与第一个过程的输入寄存器组重叠起来,形成一个窗口环,对被嵌套调用的过程循环分配窗口。在环形窗口中,调用过程将要传送的参数放人它的输出寄存器中;被调用过程将这同一组物理寄存器看作它的输入寄存器。处理器维护一个指向当前执行过程窗口的指针,称之为当前窗口指针CWP(Current Window Pointer)。CWP是处理器状态寄存器PSR的一个字段,PSR中还有一个窗口无效屏蔽WIM(Window Invalid Mask),它指示哪个窗口无效。过程调用指令通过减小CWP的值来隐藏旧的寄存器窗口,并提供新的寄存器窗口给被调用过程使用。
图2-19 SPARC中的8个寄存器窗口生成的环形结构
2.4.2 RISC指令系统实例 当过程调用嵌套得太深时,处理器将会用尽所有的寄存器窗口。这时,最旧的寄存器窗口将被调入内存,以便获得可用的寄存器窗口。与此类似,在许多过程调用返回之后,内存中的寄存器窗口会被重新调入。因此,重叠寄存器窗口技术只是在调用层次不是很多时才能有效地提高处理器的性能。 (2)SPARC指令集 SPARC指令集如表2-7所示,包括6类指令:LOAD/STORE指令、移位指令、布尔运算指令、算术指令、跳转/转移指令和其他指令。SPARC具有典型的RISC特征,所有运算操作都基于寄存器,只有LOAD/STORE指令能够访问主存储器。
表2-7 SPARC指令集 助记符 说明 LOAD/STORE指令 算术指令 LDSB 装入有符号字节 ADD 加 LDSH 装入有符号半字 ADDCC 加,设置条件码 LDUB 装入无符号字节 ADDX 带进位加 LDUH 装入无符半字 ADDXCC 带进位加,设置条件码 LD 装入字 SUB 减 LDD 装入双字 SUBCC 减,设置条件码 STB 存字节 SUBX 带借位减 STH 存半字 SUBXCC 带借位减,设置条件码 STD 存字 MULSCC 多步,设置条件码 STDD 存双字 跳转/转移指令
表2-7 SPARC指令集 移位指令 SLL 逻辑左移 BCC 按条件转移 SRL 逻辑右移 FBCC 按浮点条件转移 SRA 算术右移 CBCC 按协处理器条件转移 布尔运算指令 CALL 调用过程 AND JMPL 跳转并链接 ANDCC AND,设置条件码 TCC 按条件自陷 ANDN NAND SAVE 前移寄存器窗口 ANDNCC NAND,设置条件码 RESTORE 后移寄存器窗口 OR REIT 由自陷返回 ORCC OR,设置条件码
表2-7 SPARC指令集 ORN NOR 其他指令 ORNCC NOR,设置条件码 SETHI 设置高22位 XOR UNIMP 未实现的指令(自陷) XORCC XOR,设置条件码 RD 读专门寄存器 XRON 相异NOR WR 写专门寄存器 XRONCC 相异NOR,设置条件码 IFLUSH 指令Cache清除
2.4.2 RISC指令系统实例 运算操作指令都是寄存器到寄存器的,运算类指令有三个操作数,其功能可以表示成: RS1 op S2 → Rd 其中,RS1是寄存器操作数,S2或者是寄存器操作数或者一个13位立即数,Rd是目的寄存器。寄存器0即R0已被硬布线成为0值,R0可以用于常数或寻址需要0值的指令。 可由ALU实现操作的指令分包括:整数加法(带或不带进位),整数减法(带或不带借位),布尔运算AND、OR、XOR及其逆操作,逻辑左移、逻辑右移和算术右移。除移位指令之外,运算指令都可选择设置4个条件代码:零、负、上溢、进位。整数以32位的2的补码形式表示。
2.4.2 RISC指令系统实例 LOAD/STORE指令可以区分对字(32位)、双字、半字、字节的装入或存储。半字或字节的半入指令还可按有符号数和无符号数区别对待,前者是以符号位,后者是以0向左扩展,将32位目的寄存器左端空缺位填满。 存储器寻址方式只有一个,即存储器操作数的有效地址(EA)是基地址和偏移量之和。基地址来自寄存器,偏移量可以是立即数也可以来自于寄存器,可表示为: 或 SPARC的这个存储器寻址方式非常灵活,其不同的组合可以形成三种寻址方式,如表2-8中的后三种寻址方式。
表2-8 以SPARC寻址方式综合成其他寻址方式 一般寻址方式 寻址表示 SPARC等价寻址 SPARC指令类型 立即寻址 操作数=立即数 S2 寄存器-寄存器 寄存器寻址 R RS1,RS2 ,Rd 直接寻址 EA=A R0+S2 装入,存储 寄存器间接寻址 EA=(R) RS1+0 基址寻址 EA=(R)+A RS1+S2 与MIPS存储器寻址方式相比,SPARC存储器寻址更灵活。另一个不同是,MIPS使用16位偏移量,SPARC使用13位偏移量。
习题二 2-1 试述数据类型、数据表示和数据结构之间的关系。 2-2 浮点数据表示是否可以表示在表示范围内的所有实数?为什么? 2-3 某机器浮点数的机器字长为32位,阶码长度q=7位,尾数长度n=23位,阶码符号位和尾数符号位各占1位。尾数和阶码的基都为2,即rm=re=2,尾数用原码、纯小数表示,阶码用移码、整数表示。请给出规格化浮点数的表示范围。
习题二 2-4 某机器浮点数表示的阶码长度q=6位,阶码的值e用二进制整数、移码表示,尾数长度n=6位,尾数的值m用十六进制纯小数、补码表示。请给出规格化浮点数的表示范围。 2-5 试证明:尾数长度n相同,尾数的基不同的浮点数表示方式中,尾数的基rm=2的浮点数表示方式的规格化浮点数的表数精度最高。 2-6 设浮点数表示方式中,阶码长度q=6位,尾数长度n=48位。当尾数的基分别取值2、8、16时,求非负阶规格化正尾数浮点数的最小阶值、最大阶值、阶码的个数、尾数最小值、尾数最大值、浮点数最小值、浮点数最大值和可表示的浮点数个数。
习题二 2-7 为什么会出现标识符数据表示?标志符数据表示与描述符数据表示有何区别? 2-8 带标志符的数据表示增大了数据字的字长,是否会增大目标程序在这种机器上运行时占用的存储空间?为什么? 2-9 试说明变址寻址和基址寻址的适用场合。试设计一种只用4位地址码就可以指向一个大地址空间中任意64位地址之一的寻址机制。 2-10 指令中常用的寻址方式有:立即数寻址、寄存器寻址、直接寻址、寄存器间接寻址、间接寻址、变址寻址。试分别说明这些寻址方法的原理,并对它们在:可表示操作数的范围大小;除取指外,为获得操作数所需访主存的最少次数;为指明该操作数所占用指令中的信息位数多少;寻址复杂性程度这4个方面进行比较。
习题二 2-11 如IBM 370设有基地址寄存器,每条指令的基地址寄存器地址(4位)加位移量(12位)共16位作为地址码。现在,如果采用另一种方法即让每条指令都有一个24位的直接地址,针对下面两种情况评价这个方法的优、缺点: (1)数据集中于有限几块,但这些块分布在整个存贮空间; (2)数据均匀地分布在整个地址空间中。 你认为在实际应用中这两种情况的哪一种可能性大?为什么? 2-12 指令格式的设计需要从哪几个方面来考虑?为什么? 2-13 经过统计,某处理机的9条指令使用频度分别为:43%、13% 、7%、6% 、5%、1%、2%、22%、l%,试分别设计这9条指令操作码的哈夫曼编码、3/3/3扩展编码和2/7扩展编码,并计算这3种编码的平均码长。
习题二 2-14 某专用机用于文字处理,每个文字符用4位十进制数字(0~9)编码表示,空格则用“-”表示,在对传送的文字符和空格进行统计后,得出它们的出现频度分别为 -:20% 0:17% 1:6% 2:8% 3:11% 4:8% 5:5% 6:8% 7:13% 8:3% 9:l% (1)若上述数字和空格均用二进制码编码,试设计二进制信息位平均长度最短的编码; (2)按(1)设计的最短编码,若传送106个文字符号,且每个文字符号都跟一个空格,则共需传送多少个二进制位?若传送波特率为56Kb/s,则共需传送多少时间? (3)若对数字0~9和空格采用4位定长编码,重新计算问题(2)的要求。
习题二 2-15为什么扩展编码要求任何短码都不能是任何长码的前缀?扩展编码如何实现这一要求? 2-16 对给定的频度分布 ,由哈夫曼算法生成的哈夫曼树的结构可能不是惟一的,在什么情况下不惟一?由给定的频度分布 生成不同结构的哈夫曼树,得出哈夫曼编码的平均码长是否是惟一的? 2-17 经统计,某处理机14条指令的使用频度分别为:0.01、0.15、0.12、0.03、0.02、0.04、0.02、0.04、0.01、0.13、0.15、0.14、0.11、0.03。试分别给出指令操作码的定长编码、哈夫曼编码、只能有2种码长且平均码长尽可能短的扩展编码,并分别计算这3种编码的平均码长。
习题二 2-18 某机的指令字长16位,设有单地址指令和双地址指令2类指令。若每个地址字段均为6位,且双地址指令有x条,试求出单地址指令最多可以有多少条? 2-19 若某处理机的指令系统要求有:三地址指令4条,一地址指令255条,零地址指令16条,设指令字长为12位,每个地址码长度为3位。问能否用扩展编码为其操作码编码?如果要求单地址指令为254条,能否对其操作码扩展编码?说明理由。 2-20 一台模型机共有7条指令,各指令的使用频度分别为:35%,25%,20%,10%,5%,3%,2%;有8个通用寄存器和2个变址寄存器。 (1)试设计7条指令操作码的哈夫曼编码,并计算操作码的平均码长。 (2)若要求设计8位长的寄存器-寄存器型指令3条,16位长的寄存器-存储器型变址寻址指令4条,变址范围为-127~+127,试设计指令格式,并给出指令各字段的长度和操作码编码。
习题二 2-21 简要列举包括操作码和地址码两部分的指令格式优化可采用的各种途径和思路。除了指令格式优化外,试列举3个在计算机不同场合和用途上使用哈夫曼压缩概念的例子。 2-22 分别简述Pentium II与SPARC处理器指令格式的特点。 2-23 简述设计RISC机器的一般原则与可采用的基本技术。 2-24 为什么SPARC处理器要采用重叠寄存器窗口技术?简述该技术的工作机制。 2-25 为什么RISC处理器通常只允许LOAD/STORE指令访问主存储器? 2-26 分别简述MIPS R4000与SPARC的指令系统的寻址方式的特点。 2-26 简要比较CISC机器和RISC机器各自的结构特点,它们分别存在哪些不足和问题?为什么说今后的发展应是CISC和RISC的结合?