计算机组成原理(4.1)—— 指令系统设计

一、指令集体系结构(ISA)的基础概念

1. 指令相关概念

  • CPU只能识别指令形式的机器语言(01序列),不管C、python还是什么高级语言,都需要翻译(编译、汇编、解释)为机器语言才能执行
  • 指令可以分为三个类型
    1. 微指令微程序级的命令,它属于硬件
    2. 宏指令(伪指令):由若干条机器指令组成的软件指令,它属于软件;
    3. 机器指令:介于微指令和伪指令之间,处于硬件和软件的交界面,每一条指令可完成一个独立的算术运算或逻辑运算操作。一般讲的指令就是指机器指令
      • 一条机器指令对应了硬件层面的一段微程序,微程序由若干微指令组成。比如在多周期CPU中执行一个加法指令,它可能对应了类似这样的一段微程序:从寄存器取操作数 -> 运算 -> 结果写回寄存器,这里就是三条微指令,每个机器周期执行一条。
      • 机器指令就是一串二进制的01序列
  • 指令集(指令系统):一台机器可以执行的机器指令的集合,它是ISA的核心组成部分
  • 微架构:处理器核心的实现方式,是将一种给定的ISA在处理器中执行的方法

2. 什么是ISA

  • ISA(指令集体系结构)是一种规约(Specification),它规定了如何使用硬件,是一种对硬件的抽象
    在这里插入图片描述

  • 关系图
    在这里插入图片描述

3. ISA的地位

(1)ISA是软件和硬件的交界面(接口)

  • 计算机体系结构示意
    在这里插入图片描述
  • 指令系统处在软/硬件交界面,同时被硬件设计者和系统程序员看到
    • 硬件设计者角度:指令系统为CPU提供功能需求,要求易于硬件设计
    • 系统程序员角度:通过指令系统来使用硬件,要求易于编写编译器
  • ISA是对硬件的抽象,所有软件功能都建立在 ISA之上

(2)ISA是计算机的必要组成部分

  • ISA是最贴近CPU的,它规定了CPU可以理解的机器码语法以及部分CPU设计要求,因此它在计算机体系结构的发展中一直存在。它是CPU的接口,只要有计算机硬件,就有ISA。
  • 操作系统、各种层次的编程语言等等都是建立与ISA之上的,它们即使这些都没有,我们直接写机器码也可以让计算机正常工作
  • 计算机体系结构的发展简图如下,可以看到其中都有ISA
    1. 最早的计算机,用机器语言编程
      在这里插入图片描述
    2. 之后出现了OS和汇编语言,可以执行多道程序
      在这里插入图片描述
    3. 现代计算机体系结构
      在这里插入图片描述
  • 最后附一张不同层次的计算机工作者对计算机的认识
    在这里插入图片描述
  • 下面,针对ISA的核心组成部分——指令集(指令系统),进行进一步介绍

二、指令格式设计

1. 一条指令必须包含的信息

在这里插入图片描述

2. 不同地址码个数的指令

  • 这里的地址是指一个操作数所在的地址。它具体可能是寄存器编号、存储器地址、I/O端口或指令立即数等等…
    在这里插入图片描述

3. 从指令执行周期看指令设计涉及的问题

  • CPU的运行流程:
    • 取指令 - 指令译码 - 计算地址取操作数 - 进行运算,得标志位 - 计算结果送目的地 - 计算下条指令地址在这里插入图片描述

    • 上面这种划分得比较细,一个标准五级流水线中是这样划分的:取指 - 译码 - 执行 - 访存 - 写回

三、指令系统设计

1. 设计指令系统

(1)设计原则

  • 应尽量短
  • 要有足够的操作码位数
  • 指令编码必须有唯一的解释,否则是不合法的指令
  • 指令字长应是字节的整数倍
  • 合理地选择地址字段的个数
  • 指令尽量规整

(2)设计的重要方面

  • 操作码的全部组成:操作码个数 / 种类 / 复杂度 (主存读写、自增、跳转四种指令已足够编制任何可计算程序,但程序会很长)
  • 数据类型:对哪几种数据类型完成操作
  • 指令格式:指令长度 / 地址码个数 / 各字段长度(看上面一、2部分)
  • 通用寄存器:个数 / 功能 / 长度
  • 寻址方式:操作数地址的指定方式
  • 下条指令的地址如何确定:顺序,PC+1;条件转移;无条件转移;……
  • 一条指令的功能,一般通过对操作码进行不同的编码来定义; 操作码相同时,再由功能码进行区分(例如MIPS的R型指令)

2. 操作数类型和存储方式

  • 操作数:指令处理的对象,与高级语言的数据类型对应
  • 操作数存放在寄存器内存单元

(1)指令应涉及的基本数据类型

在这里插入图片描述

(2)IA32和MIPS中的数据类型

  1. IA-32(英特尔32位体系架构,80386开始采用)

    • 基本类型:字节、字(16位)、双字(32位)、四字(64位)
    • 整数: 16位、32位、64位三种2-补码表示的整数;18位压缩8421 BCD码表示的十进制整数
    • 无符号整数(8、16或32位)
    • 近指针:32位段内偏移(有效地址)
    • 浮点数:IEEE 754(80位扩展精度浮点数寄存器)
  2. MIPS

    • 基本类型:字节、半字(16位)、字(32位)、四字(64位)
    • 整数: 16位、32位、64位三种2-补码表示的整数
    • 无符号整数:(16、32位)
    • 浮点数:IEEE 754(32位/64位浮点数寄存器)

3. 寻址方式

(1)关于寻址

  • 寻址方式:指令或操作数地址的指定方式。即:根据地址找到指令或操作数的方法,通常特指 “操作数的寻址”
  • 指令中如何表示寻址方式
    1. 没有专门的寻址方式位(由操作码确定寻址方式):如MIPS指令,一条指令中最多仅有一个主(虚)存地址,且仅有一到两种寻址方式。
    2. 有专门的寻址方式位:如X86指令,一条指令中有多个操作数,且寻址方式各不相同, 需要各自说明寻址方式,因此每个操作数有专门的寻址方式位
  • 常用寻址方式:立即 / 直接 / 间接 / 寄存器 / 寄存器间接 / 偏移 / 堆栈…

(2)有效地址和地址编码

  1. 有效地址
    在这里插入图片描述
  2. 地址编码
    在这里插入图片描述

(3)指令的寻址

  1. 指令寻址
    在这里插入图片描述

(4)操作数的寻址

1. 常用寻址方式

在这里插入图片描述

  • EA是操作数在主存中的地址,得到EA后,还要访存才能得到操作数
  • 操作数的真实位置
    • 在指令中直接给出:立即寻址
    • 在寄存器中:寄存器寻址
    • 在主存中:以上除了立即和寄存器之外所有
    • 在磁盘中:对于在主存中的操作数,可能发生 “缺页” ,此时操作数在磁盘中,需要被置换进主存
  • 偏移寻址有三种,这块比较复杂,下面逐一分析

2. 三种偏移寻址方式详述

  1. 寻址算法思想

    1. 思维导图
      在这里插入图片描述
    2. 可见,所谓偏移寻址就是利用基地址和地址偏移量计算目标地址,根据地址给出形式的不同,可以分成三种类型。
    3. 一般RISC机器不提供自动变址寻址,并将变址和基址寻址统一成一种 “偏移寻址方式”。比如MIPS就是这样的
  2. 相对寻址: EA=A+(PC)

    • 定义:目标地址 = 相对于PC寄存器当前值的位移量为A的存储单元。指令地址码给出一个偏移量(带符号数),基准地址由PC寄存器隐含给出
    • 注意:当前PC值可能是本条指令(没有指令预取,如单周期CPU)或下一条指令的地址(有指令预取,如流水线CPU)
    • 可用来实现程序(公共子程序)的浮动指定转移目标地址
      • 公共子程序的浮动:
        在这里插入图片描述

      • 相对寻址实现相对转移

        • 举例:双字节(2个字节)定长指令字,第一字节是操作码Jxx,第二字节是位移量D,用补码表示。目标地址范围不等于位移量D的表示范围,只有确定了是按字还是字节编址、位移量D是指指令条数还是单元数,才能确定目标地址范围。若D为字节单元数,跳转范围[-126,128]单元,[-63,64]条指令
          在这里插入图片描述

        • 假设使用流水线技术,有指令预取,按字节编址,指令长度为双字节,D代表单元数,则目标地址 = (PC) +2 +D。由于流水线,在取这条Jxx指令的时候,PC已经+1了,指令长度又是双字节,所以要先加2得到此刻Jxx指令的地址,然后再加单元偏移D得到目的地址

        • 举例:若转移指令地址为2000H,转移目标地址为1FF0H,总是在取指令同时对PC增量(流水线),则转移指令第二字节位移量为多少?
          在这里插入图片描述

        • 举例:MIPS指令beq $1, $2, Label_25的转移目标地址为(PC)+4+4*25,这里的25是指令条数而不是单元数,MIPS采用定长指令字,按字节编址,所有指令的长度都是32位(4字节)。

        • 说明:MIPS采用定长指令字,按字节编址, 所有指令的长度都是32位(4字节)

  3. 基址寻址:EA=A+(B)

    • 定义:目标地址 = 相对于基址(B)处位移量为A的单元。指令地址码给出一个偏移量,基准地址 由基址寄存器B给出。 (例如MIPS指令lw / sw $s2, 0x40($t1)
    • 可用来实现多道程序重定位过程调用中参数的访问
      • 基址寻址实现程序重定位
        在这里插入图片描述
  4. 变址寻址: EA=A+(I)

    1. 定义:目标地址 = 相对于首址A处位移量为(I)的单元。指令地址码给出一个基准(形式)地址A ,而偏移量(无符号数) 由变址寄存器 I 给出。(例如Intel 8086指令MOV AL, [SI+1000H],这里SI就是I, 1000H就是A。)
    2. MIPS中没有变址寄存器;IA32中有
    3. 可为循环重复操作提供一种高效机制,如实现对线性SK表IP的方便操作
      在这里插入图片描述

4. 操作码编码

在这里插入图片描述

(1)定长操作码编码

  1. 思维导图
    在这里插入图片描述

  2. 举例:IBM360/370的指令格式
    在这里插入图片描述
    在这里插入图片描述

    • 可以看到,各种指令类型中,OP段(操作码)的编码长度都是一致的
    • IBM360/370使用了定长操作码,变长指令字

(2)变长操作码编码

  • 基本思想
    • 操作码的编码长度分成几种固定长的格式
    • 指令格式:变长操作码、变长指令字
  • 变长操作码编码有两种
    • 扩展编码
    • 哈夫曼编码
  • PDP-11是典型的变长操作码机器
  • 大多数指令集采用变长操作码编码这种方式

1. 哈夫曼编码

  • 这就是数据结构中学习过的哈夫曼编码,可以有效压缩操作码的平均长度
  • 通过构造一棵哈夫曼数,我们可以轻松获取每个操作码的哈夫曼编码,这里不展开说了
  • 哈夫曼编码应用于指令设计时存在一些问题
    • 操作码长度很不规整;
    • 硬件译码困难
    • 与地址码共同组成固定长的指令比较困难

2. 扩展编码

  1. 核心原则:任意操作码的编码不能是另一个操作码的编码的前缀

  2. 等长15/15/15扩展编码
    在这里插入图片描述

  3. 等长8/64/512扩展编码
    在这里插入图片描述

  4. 不等长操作码4/6/10扩展编码法
    在这里插入图片描述

3. 设计操作码编码示例

  • 设某指令系统指令字是16位,操作码从最高位开始,地址码都在最低位,每个地址码为6位。包含三类指令

    1. 二地址指令15条
    2. 一地址指令34条
    3. 其余为零地址指令
  • 分析:

    1. 二地址指令格式:4位操作码 | 6位地址 | 6位地址
    2. 一地址指令:10位操作码 | 6位地址
    3. 零地址指令:16位操作码
  • 编码设计:
    在这里插入图片描述

5. 标志信息的生成与使用

(1)条件测试方式

  • 在一些CPU设计中,条件转移指令通常根据Condition Codes (条件码/CC) 决定是否转移。如IA-32结构中的Jcc系列指令

  • IA-32的Jcc指令示例,可见条件码cc本质上是由一些标志位的逻辑运算结果决定的,也就是说:标志位经过逻辑运算,可以进行逻辑判断或溢出检测等
    在这里插入图片描述

  • 常见的标志位由以下四种,对于带符号和无符号运算,标志生成方式有没有不同,因为电路不知道是无符号数还是带符号整数!
    在这里插入图片描述

  • 通过执行算术指令显式地由比较和测试指令来设置CC(即设置标志位),它们(尤其是第二类)往往配合跳转转移系列指令Jcc使用

    1. 第一类:如IA-32中的addsub等算术指令
    2. 第二类:如IA-32中的cmptest等指令
  • 更多关于IA-32中标志相关的内容,请参考:IA-32汇编语言笔记(3)—— 简单传送、加减指令 & 标志寄存器

(2)标志寄存器

  • IA-32系列结构中使用了标志寄存器(程序状态字寄存器)PSW,这是一个16位的寄存器。 它反映了CPU运算的状态特征并且存放某些控制标志。8086使用了16位中的9位,包括6个状态标志位和3个控制标志位
    在这里插入图片描述
    在这里插入图片描述

(3)MIPS中没有标志位

  • MIPS架构和IA-32的一个大区别就是MIPS没有标志位的概念,自然也没有标志寄存器PSW
  • MIPS架构中,直接在ALU部件运算时生成转移发生、溢出发生等信号,这些信号被传输到其他部件控制动作发生

6. 指令设计风格

(1)按操作数位置指定风格

  1. 四种指令风格
    在这里插入图片描述

  2. 指令风格比较
    在这里插入图片描述

    • 累加器型,因为所有运算都要用累加器,表达式复杂时,程序中移入移出累加器的指令增多
    • 1975年开始,寄存器型指令集占主导地位。寄存器速度快,使用大量通用Reg减少访存;与堆栈型指令用到堆栈相比,编译高级语言中变量时,不用考虑顺序
  3. 不同指令集关于访存的比较
    在这里插入图片描述

(2)按指令格式的复杂度来分

1. 复杂指令集计算机CISC

在这里插入图片描述

2. 精简指令集计算机RISC

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wxc971231/article/details/107924644