计算机体系结构 第2章 指令系统的设计(2)

第2章 指令系统的设计

2.4 指令系统的发展和改进

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

CISC指令系统的一大特点

  • 指令数量多、功能多样

增强指令功能主要是从以下3个方面着手:

  1. 面向目标程序增强指令功能
  2. 面向高级语言的优化实现来改进指令系统
  3. 面向操作系统的优化实现改进指令系统
2.4.1.1 面向目标程序增强指令功能
  • 对大量的目标程序及其执行情况进行统计分析,找出那些使用频度高、执行时间长的指令或指令串。
    • 对于使用频度高的指令,用硬件加快其执行
    • 对于使用频度高的指令串,用一条新的指令来替代
  • 既能减少目标程序的执行时间,也能有效地缩短程序的长度。
  • 可以从以下几个方面来改进:
    • 增强运算型指令的功能
    • 增强数据传送指令的功能
    • 增强程序控制指令的功能

举例:

循环控制部分通常用3条指令完成:一条加法指令、一条比较指令、一条分支指令

设置循环控制指令,用一条指令完成上述3条指令的功能。

2.4.1.2 面向高级语言的优化实现来改进指令系统(缩小高级语言与机器语言的语义差距)
  • 高级语言与一般的机器语言的语义差距非常大,为高级语言程序的编译带来了一些问题。

    • 编译器本身比较复杂;
    • 编译生成的目标代码比较难以达到很好的优化。
  • 增强对高级语言和编译器的支持 (面向高级语言的计算机 )

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

    1. 间接执行高级语言机器
      • 高级语言作为机器的汇编语言。
    2. 直接执行高级语言的机器
      • 直接把高级语言作为机器语言。(一种比较激进的方法 )
  • 采用“比较简单的系统结构+软件”的做法能够在较低成本和复杂度的前提下,提供更高的性能和灵活性。

2.4.1.3 面向操作系统的优化实现改进指令系统
  • 操作系统和计算机系统结构是紧密联系的,操作系统的实现在很大程度上取决于系统结构的支持。
  • 指令系统对操作系统的支持主要有:
    • 处理机工作状态和访问方式的切换;
    • 进程的管理和切换;
    • 存储管理和信息保护;
    • 进程的同步与互斥,信号灯的管理等。
  • 支持操作系统的有些指令属于特权指令,一般用户程序是不能使用的。
2.4.1.4 CISC存在的问题
- 20%与80%规律
- VLSI技术的发展引起的问题
- 软硬件功能分配问题
  • 这些问题导致RISC体系结构的产生

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

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

各种指令的使用频度相差悬殊,许多指令很少用。 (二八定律)

  • 据统计:只有20%的指令使用频度比较高,占运行时间的80%。而其余80%的指令只在20%的运行时
    间内才会用到。
  • 使用频度高的指令也是最简单的指令。

分析:

  • 指令系统庞大,指令条数很多,许多指令的功能又很复杂,使得控制器硬件非常复杂。

导致的问题:

- 占用了大量的芯片面积(如占用CPU芯片总面积的一半以上),给VLSI设计造成很大的困难;
- 增加了研制时间和成本,容易造成设计错误。
  • 许多指令由于操作繁杂,其CPI值比较大,执行速度慢。采用这些复杂指令有可能使整个程序的 执行时间反而增加。

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

2.4.2.2 设计RISC机器遵循的原则
  • 指令条数少、指令功能简单。只选取使用频度很高的指令,在此基础上补充一些最有用的指令;
  • 采用简单而又统一的指令格式,并减少寻址方式;指令字长都为32位或64位;
  • 指令的执行在单个机器周期内完成;(采用流水线机制)
  • 只有loadstore指令才能访问存储器,其它指令的操作都是在寄存器之间进行;(即采用load-store结构)
  • 大多数指令都采用硬连逻辑来实现;
  • 强调优化编译器的作用,为高级语言程序生成优化的代码;
  • 充分利用流水技术来提高性能。

2.5 操作数的类型和大小

数据表示:计算机硬件能够直接识别、指令系统可以直接调用的数据类型。

  • 所有数据类型中最常用、相对比较简单、用硬件实现比较容易的几种。

数据结构:由软件进行处理和实现的各种数据类型。

  • 研究:这些数据类型的逻辑结构与物理结构之间的关系,并给出相应的算法。

系统结构设计者要解决的问题:如何确定数据表示?(软硬件取舍折中的问题)

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

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

操作数的大小: 操作数的位数或字节数。

  • 主要的大小:字节(8位)、半字(16位)、字(32位)、和双字(64位)

几种常见的操作数类型

  • 字符:用ASCII码表示,为一个字节大小。
  • 整数:用二进制补码表示,其大小可以是字节、半字或单字。
  • 浮点操作数:单精度浮点数(1个字)、双精度浮点数(双字)。一般都采用IEEE 754浮点标准
  • 十进制操作数类型
    • 压缩十进制或二进制编码十进制(BCD码):用4位二进制编码表示数字0~9,并将两个十进制数字合并到一个字节中存储。
    • 非压缩十进制:将十进制数直接用字符串来表示。

2.6 MIPS指令系统结构

2.6.1 MIPS的寄存器

  1. 32个64位通用寄存器(GPRs)
    • R0,R1,…,R31,也称为整数寄存器
    • R0的值永远是0
  2. 32个64位浮点数寄存器(FPRs)
    • F0,F1,…,F31
    • 用来存放32个单精度浮点数(32位),也可以用来存放32个双精度浮点数(64位)。
    • 存储单精度浮点数(32位)时,只用到FPR的一半,其另一半没用。
  3. 一些特殊寄存器
    • 它们可以与通用寄存器交换数据。
    • 例如浮点状态寄存器:用来保存有关浮点操作结果的信息。

2.6.2 MIPS的数据表示

  1. MIPS的数据表示
    • 整数:字节(8位) 、半字(16位)、字(32位)、双字(64位)
    • 浮点数:单精度浮点数(32位)、双精度浮点数(64位)
  2. 字节、半字或者字在装入64位寄存器时,用零扩展或者用符号位扩展来填充该寄存器的剩余部分。装入以后,对它们将按照64位整数的方式进行运算。

2.6.3 MIPS的数据寻址方式

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

2.6.4 MIPS的指令格式

  1. 寻址方式编码到操作码中
  2. 所有的指令都是32位的
  3. 操作码占6位
  4. 3种指令格式:3种格式中,同名字段的位置固定不变。
2.6.4.1 I类指令
  • 包括所有的load和store指令,立即数指令,分支指令,寄存器跳转指令,寄存器链接跳转指令。

  • 立即数字段为16位,用于提供立即数或偏移量。

image-20210323075514533

指令操作说明
load指令Regs[rs]+immediate从存储器取来的数据放入寄存器rt
store指令Regs[rs]+immediate要存入存储器的数据放在寄存器rt中
立即数指令Regs[rt] ← Regs[rs] op immediate
分支指令Regs[rs]+immediate,rt无用转移目标地址
寄存器跳转
寄存器跳转并链接
Regs[rs]转移目标地址为Regs[rs]
2.6.4.2 R类指令
  • 包括ALU指令,专用寄存器读/写指令,move指令等。

image-20210323075941962

指令操作说明
ALU指令Regs[rd]← Regs[rs] funct Regs[rt]funct为具体的运算操作编码
2.6.4.3 J类指令
  • 包括跳转指令,跳转并链接指令,自陷指令,异常返回指令。
  • 在这类指令中,指令字的低26位是偏移量,它与PC相加形成跳转的地址。

image-20210323080109654

2.6.5 MIPS的操作

2.6.5.1 MIPS指令可以分为四大类
  • load和store
  • ALU操作
  • 分支与跳转
  • 浮点操作
2.6.5.2 符号的意义
  • 传送符号
符号意义
x ← n y x←_{n}y xny从y传送n位到x
x ,   y ← z x,\ y←z x, yz把z传送到x和y
  • 下标:表示字段中具体的位;
    • 对于指令和数据,按从最高位到最低位(即从左到右)的顺序依次进行编号,最高位为第0位,次高位为第1位,依此类推。
    • 下标可以是一个数字,也可以是一个范围。
符号意义
R e g s [ R 4 ] 0 Regs[R4]_{0} Regs[R4]0寄存器R4的符号位
R e g s [ R 4 ] 56 − 63 Regs[R4]_{56-63} Regs[R4]5663R4的最低字节
  • Mem:表示主存;

    • 按字节寻址,可以传输任意个字节。
  • 上标:用于表示对字段进行复制的次数。

符号意义
0 32 0^{32} 032一个32位长的全0字段
  • 符号##:用于两个字段的拼接,并且可以出现在数据传送的任何一边。
符号意义
R e g s [ R 8 ] 32 − 63 ← 32 ( M e m [ R e g s [ R 6 ] ] 0 ) 24 # # M e m [ R e g s [ R 6 ] ] Regs[R8]_{32-63} ←_{32} (Mem[Regs[R6]]_{0})^{24} \#\# Mem[Regs[R6]] Regs[R8]326332(Mem[Regs[R6]]0)24##Mem[Regs[R6]]以R6的内容作为地址访问内存,得到的字节按符号位扩展为32位后存入R8的低32位,R8的高32位(即Regs [ R 8 ] 0 − 31 [R8]_{0-31} [R8]031)不变。
2.6.5.3 load、store和ALU指令简介
  • load和store指令
指令举例指令名称含 义
LD R2, 20(R3)装入双字 R e g s [ R 2 ] ← 64 M e m [ 20 + R e g s [ R 3 ] ] Regs[R2]←_{64} Mem[20+Regs[R3]] Regs[R2]64Mem[20+Regs[R3]]
LW R2, 40(R3)装入字 R e g s [ R 2 ] ← 64 ( M e m [ 40 + R e g s [ R 3 ] ] 0 ) 32   # #   M e m [ 40 + R e g s [ R 3 ] ] Regs[R2]←_{64} (Mem[40+Regs[R3]]_{0})^{32}\ \#\# \ Mem[40+Regs[R3]] Regs[R2]64(Mem[40+Regs[R3]]0)32 ## Mem[40+Regs[R3]]
LB R2, 30(R3)装入字节 R e g s [ R 2 ] ← 64 ( M e m [ 30 + R e g s [ R 3 ] ] 0 ) 56   # #   M e m [ 30 + R e g s [ R 3 ] ] Regs[R2]←_{64} (Mem[30+Regs[R3]]_{0})^{56}\ \#\# \ Mem[30+Regs[R3]] Regs[R2]64(Mem[30+Regs[R3]]0)56 ## Mem[30+Regs[R3]]
LBU R2,40(R3)装入无符号字节 R e g s [ R 2 ] ← 64 0 56   # #   M e m [ 40 + R e g s [ R 3 ] ] Regs[R2]←_{64} 0^{56}\ \#\#\ Mem[40+Regs[R3]] Regs[R2]64056 ## Mem[40+Regs[R3]]
LH R2, 30(R3)装入半字 R e g s [ R 2 ] ← 64 ( M e m [ 30 + R e g s [ R 3 ] ] 0 ) 48   # #   M e m [ 30 + R e g s [ R 3 ] ]   # #   M e m [ 31 + R e g s [ R 3 ] ] Regs[R2]←_{64}\\ (Mem[30+Regs[R3]]_{0})^{48} \ \#\# \ Mem[30+Regs[R3]]\ \#\#\ Mem[31+Regs[R3]] Regs[R2]64(Mem[30+Regs[R3]]0)48 ## Mem[30+Regs[R3]] ## Mem[31+Regs[R3]]
L.S F2, 60(R4)装入半字 R e g s [ F 2 ] ← 64 M e m [ 60 + R e g s [ R 4 ] ]   # #   0 32 Regs[F2]←_{64} Mem[60+Regs[R4]]\ \#\#\ 0^{32} Regs[F2]64Mem[60+Regs[R4]] ## 032
L.D F2, 40(R3)装入双精度浮点数 R e g s [ F 2 ] ← 64 M e m [ 40 + R e g s [ R 3 ] ] Regs[F2]←_{64} Mem[40+Regs[R3]] Regs[F2]64Mem[40+Regs[R3]]
SD R4, 300(R5)保存双字 M e m [ 300 + R e g s [ R 5 ] ] ← 64 R e g s [ R 4 ] Mem[300+Regs[R5]]←_{64} Regs[R4] Mem[300+Regs[R5]]64Regs[R4]
SW R4, 300(R5)保存字 M e m [ 300 + R e g s [ R 5 ] ] ← 32 R e g s [ R 4 ] Mem[300+Regs[R5]]←_{32} Regs[R4] Mem[300+Regs[R5]]32Regs[R4]
S.S F2, 40(R2)保存单精度浮点数 M e m [ 40 + R e g s [ R 2 ] ] ← 32 R e g s [ F 2 ] 0 − 31 Mem[40+Regs[R2]]←_{32} Regs[F2]_{0-31} Mem[40+Regs[R2]]32Regs[F2]031
SH R5, 502(R4)保存半字 M e m [ 502 + R e g s [ R 4 ] ] ← 16 R e g s [ R 5 ] 48 − 63 Mem[502+Regs[R4]]←_{16} Regs[R5]_{ 48-63} Mem[502+Regs[R4]]16Regs[R5]4863
  • ALU指令
    • 寄存器-寄存器型(RR型)指令或立即数型
    • 算术和逻辑操作:加、减、与、或、异或和移位等
指令举例指令名称含义
DADDU R1, R2, R3无符号加Regs[R1]← Regs[R2]+ Regs[R3]
DADDIU R4, R5, #6加无符号立即数Regs[R4]← Regs[R5]+6
LUI R1, #4把立即数装入到一个字的高16位 R e g s [ R 1 ] ← 0 32   # #   4   # #   0 16 Regs[R1]← 0^{32} \ \#\#\ 4 \ \#\#\ 0^{16} Regs[R1]032 ## 4 ## 016
DSLL R1, R2, #5逻辑左移 R e g s [ R 1 ] ← R e g s [ R 2 ] < < 5 Regs[R1]← Regs[R2]<<5 Regs[R1]Regs[R2]<<5
DSLT R1, R2, R3置小于 I f ( R e g s [ R 2 ] < R e g s [ R 3 ] ) R e g s [ R 1 ] ← 1 e l s e   R e g s [ R 1 ] ← 0 If(Regs[R2]< Regs[R3]) \\ Regs[R1]← 1\\ else\ Regs[R1]←0 If(Regs[R2]<Regs[R3])Regs[R1]1else Regs[R1]0
  • R0的用法
    • R0的值永远是0,它可以用来合成一些常用的操作。例如:
      • DADDIU R1,R0,#100 给寄存器R1装入常数100
      • DADD R1,R0,R2 把寄存器R2中的数据传送到寄存器R1

2.6.6 MIPS的控制指令

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

  • 跳转指令

    • 根据跳转指令确定目标地址的方式不同以及跳转时是否链接,可以把跳转指令分成4种。
    • 确定目标地址的方式
      • 把指令中的26位偏移量左移2位(因为指令字长都是4个字节)后,替换程序计数器的低28位;
      • 间接跳转:由指令中指定的一个寄存器来给出转移目标地址。
    • 跳转的两种类型
      • 简单跳转:把目标地址送入程序计数器。
      • 跳转并链接:把目标地址送入程序计数器,把返回地址(即顺序下一条指令的地址)放入寄存器R31
  • 分支指令(条件转移)

    • 分支条件由指令确定
      • 例如:测试某个寄存器的值是否为零
    • 提供一组比较指令,用于比较两个寄存器的值。
      • 例如:“置小于”指令
    • 有的分支指令可以直接判断寄存器内容是否为负,或者比较两个寄存器是否相等。
    • 分支的目标地址
      • 由16位带符号偏移量左移两位后和PC相加的结果来决定
    • 一条浮点条件分支指令:通过测试浮点状态寄存器来决定是否进行分支。

典型的MIPS控制指令

指令举例指令名称含义
J name跳转 P C 36 ⋅ ⋅ 63 ← n a m e < < 2 PC_{36··63}← name<<2 PC3663name<<2
JAL name跳转并链接 R e g s [ R 31 ] ← P C + 4 ; P C 36 ⋅ ⋅ 63 ← n a m e < < 2 ; Regs[R31]←PC+4;PC_{36··63}←name<<2; Regs[R31]PC+4PC3663name<<2
( ( P C + 4 ) - 2 27 ) ≤ n a m e < ( ( P C + 4 ) + 2 27 ) ((PC+4)-2^{27})≤name<((PC+4)+2^{27}) ((PC+4)227)name((PC+4)+227)
JALR R3寄存器跳转并链接 R e g s [ R 31 ] ← P C + 4 ; P C ← R e g s [ R 3 ] Regs[R31]←PC+4;PC← Regs[R3] Regs[R31]PC+4PCRegs[R3]
JR R5寄存器跳转 P C ← R e g s [ R 5 ] PC← Regs[R5] PCRegs[R5]
BEQZ R4, name等于零时分支 i f ( R e g s [ R 4 ] = = 0 )   P C ← n a m e ; if(Regs[R4]== 0)\ PC←name ; if(Regs[R4]==0) PCname
( ( P C + 4 ) - 2 17 ) ≤ n a m e < ( ( P C + 4 ) + 2 17 ) ((PC+4)- 2^{17})≤name<((PC+4)+2^{17}) ((PC+4)217)name((PC+4)+217)
BNE R3, R4, name不相等时分支 i f ( R e g s [ R 3 ] ! = R e g s [ R 4 ] )   P C ← n a m e if(Regs[R3]!= Regs[R4])\ PC←name if(Regs[R3]!=Regs[R4]) PCname
( ( P C + 4 ) - 2 17 ) ≤ n a m e < ( ( P C + 4 ) + 2 17 ) ((PC+4)-2^{17})≤name<((PC+4)+2^{17}) ((PC+4)217)name((PC+4)+217)
MOVZ R1, R2, R3等于零时移动 i f ( R e g s [ R 3 ] = = 0 )   R e g s [ R 1 ] ← R e g s [ R 2 ] if(Regs[R3]==0)\ Regs[R1]← Regs[R2] if(Regs[R3]==0) Regs[R1]Regs[R2]

2.6.7 MIPS的浮点操作

  1. 由操作码指出操作数是单精度(SP)或双精度(DP)

    • 后缀S:表示操作数是单精度浮点数
    • 后缀D:表示是双精度浮点数
  2. 浮点操作

    • 包括加、减、乘、除,分别有单精度和双精度指令。
  3. 浮点数比较指令

  4. 根据比较结果设置浮点状态寄存器中的某一位,以便于后面的分支指令BC1T(若真则分支)或BC1F(若假则分支)测试该位,以决定是否进行分支。

总结:

  • 指令系统分为三大类;
  • 寻址方式;
  • 赫夫曼编码的指令优化;
  • RISC和CISC的发展和改进;
  • 操作数的类型和大小;
  • MIPS指令系统结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值