Bootstrap

计算机组成结构—指令和指令格式

        

目录

一、指令的基本格式

 二、指令字长

1. 定长指令字结构

2.变长指令字结构

三、地址码

1.四地址指令

2.三地址指令

3.二地址指令

4.一地址指令

5. 零地址指令

四、操作码

1. 定长操作码指令格式

2. 扩展操作码指令格式

五、指令的操作数类型和操作类型

1. 操作数类型

2. 指令的操作类型


        计算机是通过连续执行一条条机器语言语句,而实现自动工作的。习惯上就把每一条机器语言的语句称为 指令,而把全部机器指令的集合称为机器的 指令系统

  • 指令(机器指令)是指计算机执行某种操作的机器语言命令。

  • 一台计算机的所有指令的集合构成该计算机的 指令系统,也称 指令集

指令系统是计算机的主要属性,位于硬件和软件的交界面上。

一、指令的基本格式

        指令由 操作码地址码(操作数地址) 两部分组成。

  • 操作码:指出指令执行什么操作和具有何种功能。例如,指出是算术加运算,还是减运算;是程序转移,还是返回操作。

  • 地址码:指岀被操作的信息(指令或数据)的地址,包括参加运算的一个或多个操作数的地址、运算结果的保存地址、程序的转移地址、被调用的子程序的入口地址等。

 二、指令字长

        指令字长 是指一条指令中所包含的二进制代码的位数,它取决于操作码的长度、操作数地址的长度和操作数的个数。不同机器的指令字长是不同的,指令字长通常取 8 的整数倍。

        按照字长是否可变,又可以将指令系统分为 定长指令字结构变长指令字结构

1. 定长指令字结构

        在一个指令系统中,若所有指令的长度都是相等的,称为 定长指令字结构(定字长指令)

        早期的计算机都是定长指令字结构,而且指令字长、机器字长、存储字长全部相等;这样每次访问某个存储单元,就可以取出一个完整的指令或者数据。

        定字长指令的执行速度快,控制简单。精简指令系统计算机(Reduced Instruction Set Compter,RISC)采用定字长指令。  

2.变长指令字结构

        随着计算机的发展,存储容量不断增大,要求处理的数据类型也越来越多,指令字长发生了很大变化。一台计算机的指令系统可以采用不同长度的指令,比如单字长指令、多字长指令。

        若指令系统中各种指令的长度随指令功能而异,就称为 变长指令字结构(变字长指令)。由于主存是按字节编址的,所以指令字长多为字节的整数倍。

        控制变长指令的电路会比较复杂,而且多字长指令需要多次访问主存才能取出一条完整指令,导致了 CPU 速度降低。

        原则上讲,短指令比长指令好,因为短指令能节省存储空间,提高取指令的速度,但也有很大的局限性。长指令占用更多的存储空间,取指令的时间也会更长,但其能扩大寻址范围或可带多个操作数。 如果长、短指令在同一机器中混合使用,就会给指令系统带来很大的灵活性。为了提高指令运行速度、节省存储空间,一般会尽可能地把常用的指令设计成单字长或者短字长的格式。

        复杂指令系统计算机 (Complex Instruction Set Compter,CISC)采用变字长指令。

三、地址码

        地址码 用来指出指令操作涉及到的数据或指令具体保存的位置,可以包括:

  • 源操作数的地址(一个或两个)

  • 操作结果的地址

  • 下一条指令的地址

        这里的 “地址” 一般指主存地址,也可以是寄存器的地址,甚至可以是 I/O 设备的地址。

        我们以主存地址为例,分析一下地址码的分配。根据地址码字段的数量不同,可以把指令再做分类:

1.四地址指令

        地址码字段最多的指令,可以包含所有的信息,共有四个地址字段:

        其中 OP 是操作码;地址码 A~1~ 为第一操作数地址,A~2~ 为第二操作数地址,A~3~ 为结果地址,A~4~ 为下一条指令的地址。

        这一指令完成的操作可以写作:

        (A_1)OP(A_2) \to (A_3)

        对 A_1A_2中存放的数据执行 OP 操作,得到的结果填入 A_3 ,然后再跳转到 A_4 位置执行下一条指令。后续指令地址可以任意填写。

        假设采用定字长指令结构,指令字长为 32 位,操作码 OP 固定为 8 位。这样,每个地址码就应该占据 6 位,那么能够寻址的地址范围为 2^6^ = 64。

        这里如果都是主存地址,那么完成这样的一条四地址指令,需要访问主存 4 次(取指令 → 取操作数 A_1→ 取操作数 A_2→ 结果写入 A_3)。

2.三地址指令

        程序中大多数指令都是顺序执行的,而程序计数器 PC 存放了当前要执行指令的地址,每次执行完会自动计算下一条指令的地址(“加 1”);所以一般并不需要在指令中直接给出下一条指令的地址,A_4可以省去,这样就得到了三地址指令。

         跟四地址指令一样,它也可以完成操作:

        (A_1)OP(A_2) \to A_3

        后续的指令地址隐含在 PC 中。如果指令字长仍为 32 位、操作码为 8 位,那么每个地址码也可以占据 8 位,能够寻址的地址范围为 2^8^ = 256。当然,完成这样一条指令同样需要 4 次访存。

3.二地址指令

        如果将操作的结果直接保存在某个操作数地址对应的存储单元,就又可以在指令中节省一个地址A_3,这样就得到了二地址指令。

         它表示执行的操作为:

(A_1)OP(A_2)\rightarrow A_1

        这里 A_1 既代表第一个源操作数的地址,也代表本次运算结果的存放地址。这种情况下,完成这一条指令同样需要 4 次访存(取指令 → 取操作数 A_1 → 取操作数 A_2 → 结果写入 A_1)。

        由于访存开销比较大,计算机运行过程中,可以将中间计算结果暂存在 CPU 的寄存器(如 ACC)中,这样就节省了最后写入主存的过程。这时的二地址指令表示执行的操作为:

(A_1)OP(A_2)\rightarrow ACC

        这种情况下,完成指令只需要 3 次访存。如果指令字长仍为 32 位、操作码为 8 位,那么每个地址码可以占据 12 位,能够寻址的地址范围为 2^12^ = 4K。  

4.一地址指令

        自然可以想到,如果把二地址指令的两种情况结合起来,把某个操作数放在寄存器中,同时计算结果也放在寄存器中,那么就又可以节省一个地址了;这就是一地址指令。

它表示执行的操作为:

(ACC)OP(A_1)\rightarrow ACC

        这里第一个操作数存放在 ACC 中,第二个操作数地址为 A_1,运算结果仍存放在 ACC 中。这样,完成指令只需要 2 次访存(取指令 → 取操作数 A_1)。

        当然,上面所讨论的都是需要两个操作数的情况;一些特殊的操作,可能只需要一个操作数,比如按位取反、自增自减操作。这时表示执行的操作为

 OP(A_1)\rightarrow A_1

因为得到的结果还要再写回到对应地址中,所以需要 3 次访存(取指令 → 取操作数 A~1~ → 结果写入 A~1~)。如果指令字长仍为 32 位、操作码为 8 位,那么地址码可以占据 24 位,能够寻址的地址范围为 2^24^ = 16M。

5. 零地址指令

        在指令系统中,还有一种指令是没有地址码的,这就是零地址指令。零地址指令中只有操作码也可以分两种情况:

  • 没有操作数的指令,比如空操作(NOP)、停机(HLT);

  • 有一个隐含操作数的指令,比如子程序返回(RET)、中断返回(IRET),这类操作利用了栈数据结构,操作数的地址就隐含在堆栈指针(SP)中。

四、操作码

        操作码的位数就代表了机器的操作种类也就是机器指令集中的指令条数。操作码的长度可以是固定的,也可以是变化的。根据操作码长度是否可变,可以分为 定长操作码变长操作码 两种指令格式。

1. 定长操作码指令格式

        定长操作码指令,是在指令字的最高位部分分配固定的若干位(定长)表示操作码。一般 n 位操作码字段的指令系统最大能够表示 2^n^ 条指令。

        这种指令格式便于计算机硬件设计,指令译码和识别时间短,广泛应用于字长较长的、大中型计算机和超级小型计算机以及 RISC(Reduced Instruction Set Compter,精简指令集计算机)中。当计算机字长为 32 位或更长时,这是常规做法。  

2. 扩展操作码指令格式

        可变长度操作码指令,是指全部指令的操作码字段的位数不固定,且分散地放在指令字的不同位置。显然,这将增加指令译码和分析的难度,使控制器的设计复杂化。

        常见的可变长度操作码是 扩展操作码。在指令字长一定的条件下,操作码的长度随地址数的减少而增加,不同地址数的指令可以具有不同长度的操作码。

在设计扩展操作码指令时,需要注意两点:

  • 不允许短操作码是长操作码的前缀;

  • 各指令的操作码一定不能重复。

        下面就是一种扩展操作码的示例。指令字长为 16 位,前 4 位为基本操作码字段 OP,另有 3 个 4 位的地址字段分别为 A_1A_2A_3

        4 位基本操作码若全部用于三地址指令,则有 16 条。如果考虑到需要扩展到较少地址的指令,则将三地址指令减为 15 条,1111 留作扩展操作码使用;二地址指令为 15 条,1111 1111留作扩展操作码使用;一地址指令为 15 条,1111 1111 1111 留作扩展操作码使用;零地址指令为 16 条。

        除了这种安排以外,还有其他多种扩展方法,如形成 15 条三地址指令、12 条二地址指令、63 条一地址指令和 16 条零地址指令,共 106 条指令;或者 12 条三地址指令、61 条二地址地址、47 条一地址指令和 16 条零地址指令。

        在通常情况下,对使用频率较高的指令分配较短的操作码,对使用频率较低的指令分配较长的操作码,从而尽可能减少指令译码和分析的时间。

五、指令的操作数类型和操作类型

1. 操作数类型

        计算机中常见的操作数类型有数字、地址、字符、逻辑数据等。

  • 数字:计算机中常见的数字有定点数、浮点数和十进制数,它们分别用不同格式的二进制编码来表达。

  • 地址:本质上也是一种数据,很多时候需要对操作数地址进行计算,可以认为是一个无符号整数。

  • 字符:文本或者字符串也是一种常见的数据形式。计算机不能直接存储和传送数据,需要按一定规则对字符进行编码;广泛使用的是 ASCII 编码。

  • 逻辑数据:除算术运算外,计算机还经常需要进行逻辑运算,此时二进制码中的 0 和 1 就应该被看作逻辑上的 “假” 和 “真”,参与逻辑与或非运算。这样的数据就是 “逻辑数据”。

2. 指令的操作类型

        设计指令系统时必须考虑应提供哪些操作类型,指令操作类型按功能可分为以下几种。

(1)数据传送

        数据传送指令通常有寄存器之间的数据传送(MOV)、从内存单元读取数据到 CPU 寄存器 (LOAD)、从CPU 寄存器写数据到内存单元(STORE)等。

(2)算术和逻辑运算

        这类指令主要有加(ADD)、减(SUB)、比较(CMP)、乘(MUL)、除(DIV)、加1 (INC)、减1 (DEC)、与(AND)、或(OR)、取反(NOT)、异或(XOR)等。

(3)移位操作

        移位操作指令主要有算术移位指令、逻辑移位指令、循环移位指令等。移位操作经常被用来替代简单的乘/除法运算。

(4)转移操作

        转移操作指令主要有无条件转移(JMP)指令、条件转移(BRANCH)指令、调用(CALL)指令、 返回(RET)指令、陷阱(TRAP)指令等。

① 无条件转移指令

        在任何情况下都执行转移操作,可以直接把程序转移到下一条要执行指令的地址。

        例如:“ JMP X ”,就是无条件跳转到地址 X 去执行下一条指令。

② 条件转移指令

        条件转移指令仅在满足特定条件时才执行转移操作,转移条件一般是一个或几个标志位的值。这些标志位是某些操作的结果,也叫做 “条件码”。例如:

  • 零标志位(ZF),当结果为 0 时,ZF = 1;

  • 负标志位(SF),结果为负时,SF = 1;

  • 溢出标志位(OF),结果溢出时,OF = 1;

  • 进位标志位(CF),最高位有进位时,CF = 1;

  • 奇偶标志位(PF),结果为偶数时,PF = 1

这样,

“ JZ X ”,就表示判断结果是否为 0:如果为 0 就跳转到 X,如果不为 0 则继续顺序执行;

“ JO Y ”,就表示判断结果是否溢出:如果溢出就跳转到 Y,如果没有溢出则继续顺序执行;

“ JC Z ”,就表示判断结果最高位是否有进位:如果有进位就跳转到 Z,如果没有则继续顺序执行。

③ 调用和返回指令

        调用指令可以实现从一个程序到另一个程序的转移操作。

        程序中,有些特定的程序段会被反复调用。为了避免重复编写,可以将这些程序段设定为 子程序;需要调用时,只需要执行子程序调用指令就可以了。还有一些子程序是系统提供的,用户也可以直接调用。

        调用指令(CALL)一般与 返回指令(RETURN)配合使用。CALL 用来从当前程序位置转移至子程序的入口,RETURN 则用于子程序执行完后重新返回到原程序的调用点。

        调用指令和转移指令的区别:执行调用指令时必须保存下一条指令的地址(返回地址),当子程序执行结束时,根据返回地址返回到主程序继续执行;而转移指令则不返回执行。

④ 陷阱(Trap)指令

        陷阱其实是一种意外事故引发的中断。比如,电压不稳定、I/O 设备发生故障、用户使用未定义的指令、除数为 0 等等各种意外事件,都会导致计算机不能继续正常工作。此时计算机就发出陷阱信号,暂定当前程序的执行,转入故障处理程序进行相应的处理。

        计算机的陷阱指令一般不提供给用户使用,而是作为隐指令,在出现故障时由 CPU 自动产生并执行。

(5)输入输出操作

        对于 I/O 单独编址的计算机,通常设有 I/O 指令。这类指令用于 CPU 与外部设备交换数据或传送控制命令及状态信息。

(6)其它操作

        计算机中还有一些通用的控制操作,比如等待(WAIT)、停机(HLT)、空操作(NOP)、开关中断、置条件码等,都有相应的指令来完成。

;