第2章 计算机系统结构的基本概念
2.1 指令集结构的分类
-
区别不同指令集结构的主要因素
- CPU中用来存储操作数的存储单元的类型
- 堆栈
- 累加器
- 通用寄存器组
- CPU中用来存储操作数的存储单元的类型
-
将指令集结构分为三种类型
- 堆栈结构
- 累加器结构
- 通用寄存器结构
- 根据操作数的来源不同,又可进一步分为:
- 寄存器-存储器结构(RM结构) (操作数可以来自存储器 )
- 寄存器-寄存器结构(RR结构):所有操作数均来自通用寄存器组
- load-store结构:只有load指令和store指令能够访问存储器
- 根据操作数的来源不同,又可进一步分为:
-
对于不同类型的指令集结构,操作数的位置、个数以及操作数的给出方式(显式或隐式)也会不同
- 显式给出:用指令字中的操作数字段给出
- 操作数字段个数
- 寻址方式
- 隐式给出:使用事先约定好的存储单元
- 堆栈栈顶
- 累加器
- 特定寄存器
- 特定存储单元
- 显式给出:用指令字中的操作数字段给出
-
通用寄存器结构
- 现代指令集结构的主流
- 在灵活性和提高性能方面有明显的优势
- 寄存器的访问速度比存储器快。
- 对编译器而言,能更容易、有效地分配和使用寄存器。
- 寄存器可以用来存放变量。
- 减少对存储器的访问,加快程序的执行速度;(因为寄存器比存储器快)
- 用更少的地址位(相对于存储器地址)来对寄存器进行寻址,从而有效地减少程序的目标代码的大小。
-
根据ALU指令的操作数的两个特征对通用寄存器型指令集结构进一步细分
-
ALU指令的操作数个数
- 3个操作数的指令
- 两个源操作数、一个目的操作数
- 2个操作数的指令
- 其中一个操作数既作为源操作数,又作为目的操作数
- 3个操作数的指令
-
ALU指令中存储器操作数的个数
- 可以是0~3中的某一个,为0表示没有存储器操作数
-
-
ALU指令中操作数个数和存储器操作数个数的典型组合
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 -
通用寄存器型指令集结构进一步细分为3种类型:
- 寄存器-寄存器型(RR型)
- 寄存器-存储器型(RM型)
- 存储器-存储器型(MM型)
-
3种通用寄存器型指令集结构的优缺点[表中(m,n)表示指令的n个操作数中有m个存
储器操作数]
扫描二维码关注公众号,回复: 15646227 查看本文章指令集结构类型 优 点 缺 点 寄存器-寄存器型 (0,3) 指令字长固定,指令结构简洁,是一种简单的代码生成模型,各种指令的执行时钟周期数相近 与指令中含存储器操作数的指令集结构相比,指令条数多,目标代码不够紧凑,因而程序占用的空间比较大 寄存器-存储器型 (1,2) 可以在ALU指令中直接对存储器操作数进行引用,而不必先用load指令进行加载。容易对指令进行编码,目标代码比较紧凑 指令中的两个操作数不对称。在一条指令中同时对寄存器操作数和存储器操作数进行编码,有可能限制指令所能够表示的寄存器个数。指令的执行时钟周期数因操作数的来源(寄存器或存储器)不同而差别比较大 存储器-存储器型 (2,2) 或(3,3) 目标代码最紧凑,不需要设置寄存器来保存变量 指令字长变化很大,特别是3操作数指令。而且每条指令完成的工作也差别很大。对存储器的频繁访问会使存储器成为瓶颈。这种类型的指令集结构现在已不用了
2.2 寻址方式
-
一种指令集结构如何确定所要访问的数据的地址?
-
当前的指令集结构中所采用的一些操作数寻址方式
- ←:赋值操作
- Mem:存储器
- Regs:寄存器组
- 方括号:表示内容
- Mem[ ]:存储器的内容
- Regs[ ]:寄存器的内容
- Mem[Regs[R1]]:以寄存器R1中的内容作为地址的存储器单元中的内容
-
采用多种寻址方式可以显著地减少程序的指令条数,但可能增加计算机的实现复杂度以及指令的CPI。
-
立即数寻址方式和偏移寻址方式的使用频度最高
-
偏移量的取值范围
- 程序所使用的偏移量大小分布十分广泛
- 较小的偏移量和较大的偏移量均占有相当大的比例
-
立即数寻址方式
-
大约1/4的load指令和ALU指令采用了立即数寻址
-
最常用的是较小的立即数;
-
有时也会用到较大的立即数(主要是用于地址计算)。
-
在指令集结构设计中,至少要将立即数的大小设置为8~16位。
-
在VAX机(支持32位立即数)上做过类似的统计,结果表明20%~25%的立即数超过16位。
-
2.3 指令集结构的功能设计
-
指令集结构的功能设计
- 确定软、硬件功能分配。即确定哪些基本功能应该由硬件实现,哪些功能由软件实现比较合适。
-
在确定哪些基本功能用硬件来实现时,主要考虑3个因素:速度、成本、灵活性
-
硬件实现的特点
- 速度快、成本高、灵活性差
-
软件实现的特点
- 速度慢、价格便宜、灵活性好
-
-
对指令集的基本要求
-
完整性、规整性、高效率、兼容性
-
完整性:在一个有限可用的存储空间内,对于任何可解的问题,编制计算程序时,指令集所提供的指令足够用
-
规整性:主要包括对称性和均匀性
- 对称性:所有与指令集有关的存储单元的使用、操作码的设置等都是对称的
- 均匀性:指对于各种不同的操作数类型、字长、操作种类和数据存储单元,指令的设置都要同等对待
-
高效率:指令的执行速度快、使用频度高。
-
兼容性:
- 在同一系列机内,指令系统,包括寻址方式和数据表示等保持基本不变;
- 可以适当增加指令、增加寻址方式,增加数据表示等;但不能减少任何已有的指令。
-
-
在设计指令集结构时,有两种截然不同的设计策略
- CISC(复杂指令集计算机)
- 增强指令功能,把越来越多的功能交由硬件来实现,并且指令的数量也是越来越多。
- RISC(精简指令集计算机)
- 尽可能地简化指令集,不仅指令的条数少,而且指令的功能也比较简单。
- CISC(复杂指令集计算机)
2.3.1 CISC指令集结构的功能设计
-
CISC结构追求的目标
- 强化指令功能,减少程序的指令条数,以达到提高性能的目的。
-
增强指令功能主要是从以下几个方面着手:
-
面向目标程序增强指令功能
-
增强运算型指令的功能
-
增强数据传送指令的功能
-
增强程序控制指令的功能
-
-
面向高级语言的优化实现来改进指令集(缩小高级语言与机器语言的语义差距)
- 高级语言与一般的机器语言的语义差距非常大,为高级语言程序的编译带来了一些问题。
- 编译器本身比较复杂。
- 编译生成的目标代码比较难以达到很好的优化。
- 增强对高级语言和编译器的支持
- 高级语言与一般的机器语言的语义差距非常大,为高级语言程序的编译带来了一些问题。
-
面向操作系统的优化实现改进指令集
-
操作系统和计算机系统结构是紧密联系的,操作系统的实现在很大程度上取决于系统结构的支持。
-
指令集对操作系统的支持主要有:
- 处理机工作状态和访问方式的切换。
- 进程的管理和切换。
- 存储管理和信息保护。
- 进程的同步与互斥,信号灯的管理等。
-
支持操作系统的有些指令属于特权指令,一般用户程序是不能使用的。
-
-
2.3.2 RISC指令集结构的功能设计
-
CISC指令集结构存在的问题
- 各种指令的使用频度相差悬殊
- 据统计:只有20%的指令使用频度比较高,占运行时间的80%,而其余80%的指令只在20%的运行时间内才会用到。
- 使用频度高的指令也是最简单的指令。
- 指令集庞大,指令条数很多,许多指令的功能又很复杂,使得控制器硬件非常复杂。导致的问题:
- 占用了大量的芯片面积(如占用CPU芯片总面积的一半以上),给VLSI设计造成很大的困难;
- 增加了研制时间和成本,容易造成设计错误。
- 许多指令由于操作繁杂,其CPI值比较大,执行速度慢。采用这些复杂指令有可能使整个程序的 执行时间反而增加。
- 由于指令功能复杂,规整性不好,不利于采用流水技术来提高性能。
- 各种指令的使用频度相差悬殊
-
设计RISC机器遵循的原则
- 指令条数少而简单。只选取使用频度很高的指令,在此基础上补充一些最有用的指令。
- 采用简单而又统一的指令格式,并减少寻址方式;指令字长都为32位或64位。
- 指令的执行在单个机器周期内完成。(采用流水线机制)
- 采用load-store结构:只有load和store指令才能访问存储器,其他指令的操作都是在寄存器之间进行
- 大多数指令都采用硬连逻辑来实现。
- 强调优化编译器的作用,为高级语言程序生成优化的代码。
- 充分利用流水技术来提高性能。
-
RISC思想的精华
- 减少CPI是RISC思想的精华
- 程序执行时间:Time=IC· CPI · T
-
同类问题的程序长度:RISC比CISC长30%-40%
-
CPI:RISC比CISC少2倍-10倍
-
RISC的速度要比CISC快3倍左右,关键是RISC的CPI更小
-
2.3.3 控制指令
-
控制指令是用来改变控制流的。
-
跳转:当指令是无条件改变控制流时,称为跳转指令。
-
分支:当控制指令是有条件改变控制流时,则称为分支指令。
-
-
能够改变控制流的指令
-
分支
-
跳转
-
过程调用
-
过程返回
-
-
控制指令的使用频度
- 改变控制流的大部分指令是分支指令(条件转移)。
-
常用的3种表示分支条件的方法及其优缺点
名 称 检测分支条件的方法 优 点 缺 点 条件码 (CC) 检测由ALU操作设置的一些特殊的位(即CC) 可以自由设置分支条件 条件码是增设的状态。而且它限制了指令的执行顺序,因为要保证条件码能顺利地传送给分支指令 条件寄存器 比较指令把比较结果放入任何一个寄存器,检测时就检测该寄存器 简单 占用了一个寄存器 比较与分支 比较操作是分支指令的一部分,通常这种比较是受到一定限制的 用一条指令(而不是两条)就能实现分支 当采用流水方式时,该指令的操作可能太多,在一拍内做不完 -
转移目标地址的表示
- 最常用的方法: PC相对寻址
- 在指令中提供一个偏移量,由该偏移量和程序计数器(PC)的值相加而得出目标地址。
- 优点
- 有效地减少表示该目标地址所需要的位数。
- 位置无关(代码可被装载到主存的任意位置执行)。
- 关键:确定偏移量字段的长度
- 模拟结果表明:采用4~8位的偏移量字段(以指令字为单位)就能表示大多数控制指令的转移目标地址了。
- 最常用的方法: PC相对寻址
-
过程调用和返回
- 除了要改变控制流之外,可能还要保存机器状态,至少也得保存返回地址(放在专用的链接寄存器或堆栈中)。
- 过去有些指令集结构提供了专门的保存机制来保存许多寄存器的内容。
- 现在较新的指令集结构则要求由编译器生成load和store指令来保存或恢复寄存器的内容。
2.4 操作数的类型和大小
-
数据表示:计算机硬件能够直接识别、指令集可以直接调用的数据类型。
- 所有数据类型中最常用、相对比较简单、用硬件实现比较容易的几种。
-
数据结构:由软件进行处理和实现的各种数据类型。
- 研究:这些数据类型的逻辑结构与物理结构之间的关系,并给出相应的算法。
-
系统结构设计者要解决的问题:如何确定数据表示?(软硬件取舍折中的问题)
-
表示操作数类型的方法有两种
- 由指令中的操作码指定操作数的类型。
- 带标志符的数据表示。给数据加上标识,由数据本身给出操作数类型。
- 优点:简化指令集,可由硬件自动实现一致性检查和类型转换,缩小了机器语言与高级语言的语义差距,简化编译器等。
- 缺点:由于需要在执行过程中动态检测标志符,动态开销比较大,所以采用这种方案的机器很少见。
-
操作数的大小:操作数的位数或字节数。
-
主要的大小:字节(8位)、半字(16位)、字(32位)、双字(64位)
-
字符:用ASCII码表示,为一个字节大小。、
-
整数:用二进制补码表示,其大小可以是字节、半字或单字。
-
浮点操作数:单精度浮点数(1个字)、双精度浮点数(双字)。一般都采用IEEE 754浮点标准
-
十进制操作数类型
- 压缩十进制或二进制编码十进制(BCD码):用4位二进制编码表示数字0~9,并将两个十进制数字合并到一个字节中存储。
- 非压缩十进制:将十进制数直接用字符串来表示。
-
2.5 指令格式的设计
-
指令由两部分组成:操作码、地址码
-
指令格式的设计:确定指令字的编码方式
- 包括操作码字段和地址码字段的编码和表示方式。
-
操作码的编码比较简单和直观
- Huffman编码法
- 减少操作码的平均位数,但所获得的编码是变长的,不规整,不利于硬件处理。
- 固定长度的操作码
- 保证操作码的译码速度。
- Huffman编码法
-
操作码的三种编码方法:
-
固定长度、Huffman编码、扩展编码
-
优化操作码编码的目的:节省程序存储空间
-
Huffman操作码的主要缺点:
-
操作码长度很不规整,硬件译码困难
-
与地址码共同组成固定长的指令比较困难
-
-
扩展编码法:由固定长操作码与Huffman编码法相结合形成
-
-
两种表示寻址方式的方法
- 将寻址方式编码于操作码中,由操作码描述相应操作的寻址方式。
- 适合:处理机采用load-store结构,寻址方式只有很少几种。
- 设置专门的地址描述符,由地址描述符表示相应操作数的寻址方式。
- 适合:处理机具有多种寻址方式,且指令有多个操作数。
- 将寻址方式编码于操作码中,由操作码描述相应操作的寻址方式。
-
考虑因素
- 机器中寄存器的个数和寻址方式的数目对指令平均字长的影响以及它们对目标代码大小的影响。
- 所设计的指令格式便于硬件处理,特别是流水实现。
- 指令字长应该是字节(8位)的整数倍,而不能是随意的位数。
-
指令集的3种编码格式
-
变长编码格式、定长编码格式、混合型编码格式
-
变长编码格式
- 当指令集的寻址方式和操作种类很多时,这种编码格式是最好的。
- 优点:用最少的二进制位来表示目标代码。
- 缺点:可能会使各条指令的字长和执行时间相差很大。
-
定长编码格式
- 将操作类型和寻址方式一起编码到操作码中。
- 当寻址方式和操作类型非常少时,这种编码格式非常好。
- 可以有效地降低译码的复杂度,提高译码的速度。
- 大部分RISC的指令集均采用这种编码格式。
-
混合型编码格式
- 提供若干种固定的指令字长。
- 以期达到既能够减少目标代码长度,又能降低译码复杂度的目标。
-
2.6 MIPS指令集结构
2.6.1 MIPS的寄存器
-
32个64位通用寄存器(GPRs)
- R0,R1,…,R31
- 也被称为整数寄存器
- R0的值永远是0
-
32个64位浮点数寄存器(FPRs)
- F0,F1,…,F31
- 用来存放32个单精度浮点数(32位),也可以用来存放32个双精度浮点数(64位)。
- 存储单精度浮点数(32位)时,只用到FPR的一半,其另一半没用。
-
一些特殊寄存器
- 它们可以与通用寄存器交换数据。
- 例如,浮点状态寄存器用来保存有关浮点操作结果的信息。
2.6.2 MIPS的数据表示
- MIPS的数据表示
- 整数
- 字节(8位) 半字(16位)
- 字(32位) 双字(64位)
- 浮点数
- 单精度浮点数(32位) 双精度浮点数(64位)
- 整数
- 字节、半字或者字在装入64位寄存器时,用零扩展或者用符号位扩展来填充该寄存器的剩余部分。装入以后,对它们将按照64位整数的方式进行运算。
2.6.3 MIPS的数据寻址方式
- 只有立即数寻址与偏移量寻址两种寻址
- 立即数字段和偏移量字段都是16位的。
- 寄存器间接寻址是通过把0作为偏移量来实现的
- 16位绝对寻址是通过把R0(其值永远为0)作为基址寄存器来完成的
- MIPS的存储器是按字节寻址的,地址为64位
- 所有存储器访问都必须是边界对齐的
2.6.4 MIPS的指令格式
-
寻址方式编码到操作码中
-
所有的指令都是32位的
-
操作码占6位
-
3种指令格式
-
I类指令
- 包括所有的load和store指令、立即数指令、分支指令、寄存器跳转指令、寄存器链接跳转指令。
立即数字段为16位,用于提供立即数或偏移量。
-
R类指令
- 包括ALU指令、专用寄存器读/写指令、move指令等。
-
J类指令
-
包括跳转指令、跳转并链接指令、自陷指令、异常返回指令。
-
在这类指令中,指令字的低26位是偏移量,它与PC值相加形成跳转的地址。
-
2.6.5 MIPS的操作
-
MIPS指令可以分为四大类
- load和store
- ALU操作
- 分支与跳转
- 浮点操作
-
符号的意义
- 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字段
-
符号##:用于两个字段的拼接,并且可以出现在数据传送的任何一边。
- 举例:R8、R10:64位的寄存器,则Regs[R8]32…63 ←32 (Mem [Regs[R6]]0)24
- ## Mem [Regs[R6]]
- 表示的意义是:
- 以R6的内容作为地址访问内存,得到的字节按符号位扩展为32位后存入R8的低32位,R8的高32位(即Regs[R8]0…31)不变。