指令格式

指令的一般格式

  • 操作码:指令中用来表示操作性质及功能的部分,是指令的中心。
    • 固定操作码:所有指令的操作码字段长度固定。优点是译码简单,易于硬件实现;缺点是指令条数受限。
    • 扩展操作码(可变长操作码):将操作码和地址码的某些位组合,实现操作码长度可变。通常将短操作码用于常用指令,长操作码用于不常用指令。在指令字长固定的前提下,通过牺牲地址码位数来增加操作码位数,从而增加指令条数
  • 地址码:指令中指出操作数或指令的地址的部分。地址码的位数决定了指令能直接寻址的范围。
  • 寻址方式
    • 显式包含:指令字中直接给出操作数的地址,或者指明操作数存放的寄存器编号、存储单元地址等。地址码直接指出操作数的物理位置
    • 隐式包含:操作数地址不直接在指令字中给出,而是通过某种约定(如默认使用累加器 ACC、栈顶指针 SP 等),或者通过指令执行过程中的特定机制(如 PC 值、基址寄存器内容等)来确定。无需地址码明确指出操作数位置

指令字长

  • 定长指令系统:所有指令的字长都相同。
    • 特点:指令的取指和译码过程简单,便于实现并行处理和流水线技术。
    • 优点:控制简单,有利于提高指令执行速度。
    • 缺点:指令编码效率不高,灵活性差。常用指令和不常用指令都占用相同长度,可能导致指令密度较低。
  • 变长指令系统:不同指令的字长可以不同。
    • 特点:指令的取指和译码过程相对复杂,需要根据操作码判断后续指令的长度。
    • 优点:指令编码效率高,灵活性强。可以根据指令功能和操作数数量灵活分配字长,从而提高存储空间利用率和指令密度。
    • 缺点:控制逻辑复杂,不利于实现并行处理和流水线技术。
  • 指令字长分类(按与机器字长关系):指令字长通常是字节的整数倍,与机器字长的关系影响取指效率和存储效率。
    • 半字长指令:指令字长等于机器字长的一半。通常用于微型机或对存储空间要求高的系统。
    • 单字长指令:指令字长等于机器字长。这是最常见的情况,一条指令恰好占用一个机器字。
    • 多字长指令:指令字长是机器字长的整数倍(如双字长、三字长等)。用于需要更多地址位或立即数等情况,但取指需要多次访存。

指令中的地址码字段

  • 三地址指令
    • 格式与操作:通常为 OP A1, A2, A3。其操作含义通常为 (A1) ← (A2) OP (A3),即将地址 A2 和 A3 所指的操作数进行 OP 运算,结果存入地址 A1。这里的 A1、A2、A3 可以是寄存器地址或内存地址。
    • 特点
      • 一条指令可以完成一个相对复杂的运算,如 ADD R1, R2, R3 表示 R1 = R2 + R3
      • 指令字长较长,因为需要编码三个地址信息。
      • 程序代码长度较短,执行效率相对较高,因为一条指令能完成更多工作,减少了指令条数和访存次数。
    • 汇编关键字示例ADD R1, R2, R3, SUB R4, R5, R6, MUL R7, R8, R9
  • 二地址指令
    • 格式与操作:通常为 OP A1, A2。其操作含义通常为 (A1) ← (A1) OP (A2),即将地址 A1 和 A2 所指的操作数进行 OP 运算,结果存回地址 A1。A1、A2 可以是寄存器地址或内存地址。
    • 特点
      • 是最常用的指令格式之一,兼顾了指令的效率和长度。
      • 指令字长适中,比三地址指令短,比一地址指令长。
      • 运算结果会覆盖其中一个源操作数(A1),即具有破坏性
    • 汇编关键字示例MOV AX, BX, ADD DX, [SI], SUB CX, 5
  • 一地址指令
    • 格式与操作:通常为 OP A1。其操作含义通常为 (ACC) ← (ACC) OP (A1),即隐含使用**累加器(ACC)**作为其中一个操作数和运算结果的存放地址。
    • 特点
      • 指令字长较短,只需编码一个显式地址信息。
      • 程序代码长度较长,因为完成一个复杂运算需要多条指令配合(如 LOAD AADD BSTORE C)。
      • 对累加器 ACC 的依赖性强,通常需要频繁地进行累加器与内存之间的数据交换。
    • 汇编关键字示例LOAD A, ADD B, STORE C, MUL D
  • 零地址指令
    • 格式与操作:通常为 OP。指令本身不包含地址码,操作数隐含在堆栈中。例如,ADD 指令表示将栈顶的两个操作数弹出,相加后结果再压入栈顶。
    • 特点
      • 指令字长最短,因为无需编码地址信息。
      • 程序代码长度最长,因为所有操作数都需要通过 PUSHPOP 指令显式地压栈或弹栈。
      • 依赖于堆栈机的结构,操作数在堆栈中,访问速度快,但需要额外的堆栈管理指令。
      • 优点是指令译码简单,指令系统简洁。
    • 汇编关键字示例PUSH A, POP B, ADD, SUB, MUL, DIV

指令中的操作码字段

  • 操作码指定需要进行的操作运算),是指令中最重要的字段之一。
  • 不同指令的操作码编码值不同,用于区分不同的指令功能。
  • 根据操作码的长度是否固定,可分为 2 种
    • 定长操作码
      • 操作码的长度固定,并且其在指令中的位置也是固定的。
      • 指令译码简单硬件实现简单,有利于指令流水线的实现。
      • 指令系统的规模(指令系统所包含的指令数量),决定了操作码的位数。若指令系统所包含的指令数量操作码的位数,则 应满足如下关系:(即 )。
    • 变长操作码
      • 操作码的长度可变,并且其在指令中的位置也不固定
      • 可以有效减少操作码的平均长度,用较短的指令字长表示了更多的指令,并且给地址码留出了更多位数,以增大寻址空间
      • 常见实现方法:扩展操作码技术

变长操作码的常见实现 - 扩展操作码技术

  • 核心思想操作码的长度随地址码字段中地址码数量的减少而增加
  • 基本原理
    • 固定长度的指令字中,通过利用地址码字段的空闲位来扩展操作码的长度。
    • 对于需要地址数较多的指令(如三地址指令),其操作码较短,占用较少位数。
    • 对于需要地址数较少的指令(如一地址指令、零地址指令),其操作码较长,通过使用地址码字段的一部分作为操作码的扩展位来实现。
    • 这种设计允许在有限的指令字长内表示更多不同类型(不同地址数)的指令,同时提高编码效率
  • 实现机制(通常按地址数递减的方式设计)
    • 将指令字划分为若干字段,例如操作码字段和多个地址码字段。
    • 为支持不同地址数的指令,将部分短操作码的编码空间(通常是最高位字段的操作码)保留,作为扩展前缀逃逸码,指示实际操作码将延伸到后续的地址码字段中。
    • 示例:假设指令字长固定,包含一个 k 位操作码和 m 位地址码字段(共 N 个地址码字段,例如 A1, A2, ..., AN)。
      • 多地址指令(如 N 地址指令):直接使用 k 位操作码。从 2^k 种编码中,留出若干个作为扩展前缀。
      • 少地址指令(如 N-1 地址指令):当 k 位操作码为某个特定扩展前缀时,表示操作码将延伸到 AN 字段,形成 k + m 位的操作码。此时,原 AN 字段被操作码占用,指令只有 N-1 个地址字段。
      • 更少地址指令(如 N-2 地址指令):当 k + m 位操作码为某个特定扩展前缀时,表示操作码将进一步延伸到 AN-1 字段,形成 k + 2m 位的操作码。此时,原 AN-1AN 字段都被操作码占用,指令只有 N-2 个地址字段。
    • 依此类推,地址码字段越少,可用于扩展操作码的位数越多,从而可表示的指令种类也越多。
    • 通过此机制,短指令(如三地址指令)占用短操作码,而长指令(如零地址指令)虽然地址码字段减少,但可拥有更长的操作码,从而互不冲突,且充分利用了指令字长。

前缀区分指令

  • 二地址指令的操作码只能使用三地址指令不用的剩余状态
  • 一地址指令的操作码只能使用二地址指令不用的剩余状态
  • 零地址指令的操作码只能使用一地址指令不用的剩余状态