type
status
date
slug
summary
tags
category
icon
password
本章概念
- 指令:一系列按照某种规律有序排列的,能被CPU识别、执行的二进制代码。
- 指令系统(指令集):一台计算机所能执行的全部指令的集合。
- 所以:指令系统是计算机软硬件之间的界面
- 地址结构:在指令中明确给出几个地址,给出哪些地址。
指令格式
指令基本格式
- 一条指令需要提供两个方面的信息:
- 操作码:与CPU操作有关的信息
- 地址码:与操作数有关的信息(因为常常给出的是操作数的地址,所以这里叫做地址码)
- 如下图:
指令字长(关于指令的长度)
- 指令的两种格式
- 定长指令格式:控制简单
- 变长指令格式:合理利用存储空间
- 改变指令字长长度
- 优点:可丰富指令功能(位数变多了可以区分不同的指令)
- 缺点:
- 占用存储空间大(因为指令变长了)
- 从主存中取指时间长(因为需要取出的位数变多了)
- 指令执行速度慢(因为解码更难了)
操作码结构(关于指令中的操作码)
操作码的位数决定了操作类型的多少。(位数越多能表示的操作越多)
- 操作码的三种格式
- 定长操作码:指令长度比较长时,操作码位置、位数固定,一般在指令的高位;
- 扩展操作码:指令长度比较短时,操作码位置、位数不固定,用扩展标志表示。
- 扩展操作码示例如下:
- 方式码:操作码分为几部分,每部分表示一种操作。
也就是将高位的某些操作码编码留出来用于扩展操作数更少的指令
如下图:
上面就是将7-15位的操作码分成几个部分了
指令中的地址结构(关于指令中的地址码)
- 指令中所需操作数的地址形式(也就是地址码的获取形式)
- 显地址:在指令中显示地给出地址码,如主存储单元号或CPU的寄存器编号(就是直接给出操作数)
- 隐地址:指令中不给出地址码,以隐含方式约定(如进行堆栈操作的时候就隐含了sp)
- 根据定义,地址结构是指令中给出几个地址,给出哪些地址,所以简化地址结构就是要少给出地址码。即简化地址结构的基本途径:尽量使用隐地址。
- 四地址指令(给出四个地址码)
- 如下图:
- 三地址指令(给出三个地址码)
- 如下图:
相较于四地址指令,三地址指令将下一条指令的地址隐式存储在PC寄存器中(也就是下条指令地址采用隐地址形式)
- 二地址指令:多数情况下(所以大部分指令都是二地址指令),两个操作数运算后至少有一个数不再使用,因而不需要保留
- 如下图:
相较于三地址指令,二地址指令将结果存放地址隐式规定为A1(也就是将运算结果存储在A1提供的地址的空间内)
- 一地址指令
- 一地址指令的表示方式
- 隐含约定目的地的双操作数指令(实际上上面的二地址指令就是隐含目的地的三地址指令,三地址指令就是隐含下条指令的四地址指令)
- 如(这里的AC就是隐含的目的操作数):
- 只有目的操作数的单操作数指令(实际上上面的二地址指令也有可能是因为操作只需要两个操作数,三四地址指令是同样的道理,所以应该所有的指令都是应该有这两种类型的)
- 如(这个时候指令只需要一个目的操作数即可,然后将结果存回目的地址):
- 零地址指令
- 与一地址指令相同,零地址指令也有两种表示方式:
- 单操作数指令,隐含在指定寄存器内进行操作(有操作数,但是将操作数隐含)
- 不需要操作数的指令(如NOP:空操作指令,起到延时作用,或者HLT:停机指令)
本节习题
指令寻址方式
操作数存储位置
- 寄存器
- CPU中的寄存器
- 外设接口中的寄存器(并不会在外设中,因为外设和CPU是通过接口传输数据的)
- 存储器
- 主存(包括Cache,是主存和CPU之间的高速缓冲)
- 外存
- 堆栈(这个实际上是算在前两个存储位置里面的,但是堆栈操作比较特殊就单独拿出来说)
- 主存空间(软堆栈)
- CPU中的寄存器组(硬堆栈)
CPU能够直接访问的操作数在CPU内寄存器、主存储器(含Cache及接口寄存器访问。cache跟CPU直接连接,而接口可以通过单独编址和统一编址直接被CPU访问)
由于主存储器容量远远大于CPU内的寄存器的容量,因此CPU能直接访问的操作数主要存放在主存储器(cache存储的是当前最紧需的数据)。
寻址方式
- 立即寻址:指令中直接给出操作数,即在取出指令的同时也就取出了可以立即使用的操作数。
- 常用于提供初值
- 速度快,灵活性差(都是因为不需要访存了)
- 直接寻址类:由指令直接给出操作数地址(存储单元号或寄存器号,所以可以把寄存器号理解为一个地址,这个地址指向的就是当前的寄存器)
- (主存)直接寻址方式:操作数存放在主存单元中, 指令中给出的地址码是主存单元号(也就是给出主存地址),此时需要访存一次(因为需要访问存储器,所以速度慢;因为给出的地址码是比寄存器编号长的,所以地址的位数多)
- 如下图:
- 寄存器直接寻址方式(又简称为寄存器寻址):操作数存放在寄存器中,指令中给出的地址码是寄存器名称/编号(寄存器的编号就相当于是寄存器的地址)。此时不需要访存,因为数是在CPU内寄存器中的(因为寄存器在CPU内部,所以速度快;因为给出的是寄存器号而不是主存地址码,所以地址位数少)
- 采用隐地址可以减少指令中地址的数目
- 采用寄存器型寻址(这里说的是寄存器型寻址,而不是寄存器寻址,所以是包括了寄存器间址的)可以减少指令中地址码的位数
注意这里的括号就是取一次值的意思
主存直接寻址例题:
模型机内的寄存器编号如下图:
实际上也是二进制数跟十进制数的对应,其他特殊的寄存器跟在后面就好了
如下图:
括号的含义相同,下面不在赘述
寄存器寻址例题:
tips:减少指令中地址数目与减少一个地址码的位数是两个不同的概念
以上两种方式均减少了指令长度。
- 间接寻址类:间接寻址类的操作数都在主存储器中(访存不可避免),寻址过程需要先得到操作数所在主存单元的地址。
- 主存间接寻址方式:指令中给出的地址码是间接地址(是主存的地址码)
- 如下图:
- 寄存器间接寻址方式(又称为寄存器间址):指令中给出的地址码是寄存器编号,寄存器中存放操作数地址(此时存放的就是主存地址)
- 自增型寄存器间址方式(出栈操作,也是寄存器间址的一种):按照寄存器间址方式获取操作数后,寄存器的值加1(当堆栈是向下增长并且是满堆栈的时候可以用作出栈操作。考试的时候如果忘记了就可以看那个加号在哪里,自增型寄存器间址加号是写在后面的,所以是取出来再增加),可以读取地址增大方向上的一片数据
- 自减型寄存器间址方式(入栈操作):寄存器间址的又一种变型;指定的寄存器内容减1,然后按照寄存器间址方式获取操作数(同样自减型寄存器间址的减号会写在前面,所以是先减然后再进行操作),可以读取地址减小方向上的一片数据
- 堆栈寻址(实际上就是自增型和自减型寄存器间址的组合,只不过将间址寄存器隐含指定为堆栈指针寄存器SP,所以这个时候少了一个地址码,简化了指令的地址结构):注意模型机中常用的堆栈是向下增长的满堆栈(也就是栈顶指针指向的位置是有栈内元素的)
主存间接寻址例题如下:
如下图:
寄存器间址例题如下:
如下图:
自增型寄存器间址例题如下:
如下图:
自减型寄存器间址例题如下:
堆栈寻址例题:
- 变址类:通过计算得到有效地址,使地址表示灵活可变
- 变址寻址:指令中一个地址码包含两个信息:形式地址D,变址寄存器Rx(此时寄存器中给出的是地址的偏移量,也就是给出变址)。操作数有效地址 A= D+(Rx),根据A访问主存储器,读写操作数S。
- 如下图:
- 基址寻址:指令中一个地址码给出了两个信息:形式地址D,基址寄存器RB(此时寄存器中给出的是基址。记忆:是什么寻址方式,寄存器中存储的就是什么,如变址寻址中寄存器就是存储变址)。有效地址A= D+(RB)。根据A访问主存储器,读写操作数S。
- 变址寻址和基址寻址的异同:
- 相同点:有效地址计算方法相同(都是两个地址做加法得到直接地址);在一些计算机中由相同硬件实现(加法器)。
- 不同点:
- 变址寄存器提供修改量(可变),而指令中提供基准量(固定);基址寄存器提供基准量(固定),而指令中提供位移量(可变)。(是哪一种寻址方式,寄存器中就是存储什么信息)
- 变址寻址面向用户,用于访问数组等批量数据;而基址寻址面向系统,主要用于逻辑地址和物理地址(存储器中的实际地址)的转换
- 基址加变址方式:此时指令中给出两个寄存器,一个基址寄存器,一个变址寄存器,计算直接地址就是将基址,变址,形式地址相加
- 相对寻址(也称浮动编址):是基址寻址的特例,PC(程序计数器)作为基址寄存器
注意,形式地址是放在当前指令中的
变址寻址例题:
如下图:
形式上跟变址寻址是一样的,都是两个地址加起来
基址寻址的例题:
如下图:
相对寻址例题:
注意取出一次指令的时候,PC就已经指向下一条指令的开始了(要小心指令的长度和主存编址单元)
寻址方式总结
- 以上四类寻址方式,重点弄清楚“数在哪里”(在指令中、在CPU寄存器中、在主存中?)
- 如果操作数在主存中,指令直接给出有效地址(直接寻址)还是间接给出地址(寄存器间址、存储单元间址)?
- 如何通过计算使地址量可变 (形式地址与变址寄存器内容加、与基址寄存器内容加、与PC内容加或拼接。拼接在MIPS32架构CPU中有提到)?
指令类型
指令分类
- 按指令格式分类(就是有几个地址码,指令是几地址的):双操作数指令、单操作数指令等
- 按操作数寻址方式分类(R是寄存器,S是存储器,I是立即数):
- RR型(寄存器—寄存器型)
- RX型(寄存器—变址型)
- RS型(寄存器—存储器型)
- SI型(存储器—立即数型)
- SS型(存储器—存储器型)
- 按指令功能分类:
- 传送指令:CPU内部、CPU与主存之间的数据转移
- 输入/输出(I/O)指令:CPU与外设,主存与外设之间的数据转移
- 运算指令(算术运算\逻辑运算指令):与ALU有关
- 程序控制类指令:跳转等
- 处理机控制类指令等:软中断指令等
传送类指令
- 一般传送指令
- 设置传送指令时,需考虑的主要问题:
- 传送范围:即指令允许数据在什么范围内传送(寄存器到寄存器,还是存储器到存储器,还是存储器和寄存器之间)。
- 传送单位:即数据可以按字节、字(这个字就是基本字长)、双字或数组为单位进行传送
- 设置寻址方式
- 堆栈指令
- 压栈操作:将数据压入堆栈栈顶(这里说的是软堆栈),可视为存入数据到主存某一单元的一个特例
- 出栈:从堆栈栈顶弹出数据(这里说的是软堆栈),可视为读出主存某一单元中数据的一个特例
- 数据交换指令:双向数据传送,即将源操作数与目的操作数(一个字节或一个字)相互交换位置
输入/输出(I/O)指令
I/O指令是广义的传送指令,只不过数据传送的一方(接收数据或者发送数据)为输入/输出(I/O)设备
- 外围设备编址方式(影响io指令的形式:是单独一种指令,还是使用mov指令)
- 对外围设备单独编址(此时使用单独的IO指令)
- 单独编址到设备级:为每台外围设备分配一个设备码,在I/O指令中给出设备码,并指明是哪个寄存器
- 单独编址到寄存器级:为各I/O接口中的有关寄存器分配一种I/O端口地址(每个寄存器都有一个自己的IO端口地址),即编址到寄存器一级
- 外围设备与主存储器统一编址(此时IO指令也是使用MOV指令):统一编址到寄存器级, 每个外围设备接口中的一个寄存器视作一个主存单元,分配一个存储单元地址(这个时候就会导致一些主存地址,或者说地址码被外设占用,就没办法访问主存的这些位置,进而导致主存的利用率比较低)
- I/O指令设置(根据外围设备不同的编址方式来进行不同的I/O指令设置)
- 设置专用的I/O指令:IN,OUT。
- 如采用设备编码方式(也就是单独编址到设备级),则I/O指令地址码部分应给出所要访问的外围设备编码,并指定所访问的寄存器
- 如果采用I/O端口地址编码方式(也就是单独编址到寄存器级),则I/O指令地址段给出端口地址(直接/间接寻址)
- 采用通用的数据传送指令MOV实现I/O操作:隐式I/O指令(这个时候IO指令使用MOV指令实现,没有显式的IN OUT,所以称为隐式IO),适合外围设备(I/O接口寄存器)与主存单元统一编址(也就是上面说的外围设备与主存储器统一编址),以相同指令(MOV)访问存储器和外设。
本章总结及习题
本章总结
- 指令、指令系统的概念(见本章概念)
- 指令的基本格式,包含操作码和地址码
- 指令地址结构及简化思想:减少地址码数量(采用隐地址)、减少指令地址码长度(采用寄存器型寻址)
- 四大类寻址方式(立即数寻址、直接寻址、间接寻址、变址类寻址)寻找操作数的过程;
- 指令类型;
- 外设编址方式:单独编址、统一编址;
- I/O指令类型:专用I/O指令,通用传送指令
本章习题
- 作者:Noah
- 链接:https://imnoah.top/article/CptStructure/Chapter2
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。