机器指令
计算机能够解题是由于机器本身存在一种语言,它既能理解人的意图,又能被机器自身识别。机器语言由一条条语句构成,每一条语句又能准确表达某种语义,例如,它可以命令机器做某种操作,指出参与操作的数或其他信息在什么地方等。计算机就是连续执行每一条机器语句而实现全自动工作的。人们习惯把每条机器语言的语句称为机器指令,又将全部机器指令的集合称为机器的指令系统。
指令的一般格式
指令由操作码和地址码两部分组成。
(1)操作码
操作码用来指明该指令所要完成的操作,如加法、减法、传送、移位、转移等。通常,其位数反映了机器的操作种类。
① 长度固定
将操作码集中放在指令字的一个固定长度的字段内,用于指令字长较长的情况。
这种格式便于硬件设计,指令译码时间短,广泛用于字长较长的、大中型计算机和超小型计算机以及 RISC(Reduced Instruction Set Computer)中。例如,IBM 370 和 VAX-11 系列机,操作码长度均为 8 位。
② 长度可变
对于操作码长度可变的指令,其操作码被分散在指令字的不同字段中。这种格式可有效地压缩操作码的平均长度,在字长较短的微型计算机中被广泛采用。例如 PDP-11、Intel 8086 等。
③ 扩展操作码技术
操作码长度不固定会增加指令译码和分析的难度,使控制器的设计复杂。通常采用扩展操作码技术,使操作码的长度随着地址数的减少而增加,不同地址数的指令可以具有不同长度的操作码。
下图是一种扩展操作码的安排示意图。指令字长为 16 位,其中 4 位为基本操作码字段 OP,另有 3 个 4 位长的地址字段为 A 1 , A 2 , A 3 A_1,A_2,A_3 A1,A2,A3。4 位基本操作码若全部用于三地址指令,则有 16 条。若采用扩展操作码技术,当操作码取 4 位时,三地址指令最多有 15 条;操作码取 8 位时,二地址指令最多为 15 条;操作码取 12 位时,一地址指令最多为 15 条;操作码取 16 位时,零地址指令为 16 条。共 61 条,可见操作码位数随着地址数的减少而增加。
除了这种安排以外,还有其他多种扩展方法,例如,形成 15 条三地址指令(0000.X.X.X ~ 1110.X.X.X),12 条二地址指令(1111.0000.X.X ~ 1111.1011.X.X),31 条一地址指令(1111.1100.0000.X ~ 1111.1111.1110.X)和 16 条零地址指令(1111.1111.1111.0000 ~ 1111.1111.1111.1111),共 74 条指令,设计者可自行安排。
在设计操作码不固定的指令系统时,应尽量考虑安排指令使用频度(即指令在程序中出现的概率)高的指令占用短的操作码,对使用频度低的指令可占用较长的操作码,这样可以缩短经常使用的指令的译码时间。当然,考虑操作码长度时也应考虑地址码的要求。
(2)地址码
地址码可用来指出该指令的源操作数的地址(一个或两个)、结果的地址以及下一条指令的地址。这里的“地址”可以是主存的地址,也可以是寄存器的地址,甚至可以是 I/O 设备的地址。
下面以主存地址为例,分析指令的地址码字段。
① 四地址指令
该指令完成 ( A 1 ) O P ( A 2 ) → A 3 (A_1)OP(A_2)\rightarrow A_3 (A1)OP(A2)→A3 的操作。
这种指令直观易懂,可直接寻址的地址范围与地址字段的位数有关。如果指令字长为 32 位,操作码占 8 位,四个地址字段各占 6 位,则指令操作数的可直接寻址范围为 2 6 = 64 2^6=64 26=64。如果地址字段均指示主存的地址,则完成一条四地址指令,共需访问 4 次存储器(取指令一次,取两个操作数两次,存放结果一次)。
因为程序中大多数指令是按顺序执行的,而程序计数器 PC 既能存放当前欲执行指令的地址,又有计数功能,因此它能自动形成下一条指令的地址。这样,指令字中的第四地质字段 A 4 A_4 A4 可省去,即得三地址指令格式。
② 三地址指令
该指令完成 ( A 1 ) O P ( A 2 ) → A 3 (A_1)OP(A_2)\rightarrow A_3 (A1)OP(A2)→A3 的操作,后续指令的地址隐含在程序计数器 PC 中。同理,若地址字段均为主存字段,则完成一条三地址指令也需访问 4 次存储器。
机器在运行过程中,没有必要将每次运算结果都存入主存中,中间结果可以暂时存放在 CPU 的寄存器(ACC)中,这样又可省去一个地址字段 A 3 A_3 A3,从而得出二地址指令。
③ 二地址指令
该指令可完成 ( A 1 ) O P ( A 2 ) → A 1 (A_1)OP(A_2)\rightarrow A_1 (A1)OP(A2)→A1 或 ( A 1 ) O P ( A 2 ) → A 2 (A_1)OP(A_2)\rightarrow A_2 (A1)OP(A2)→A2 或 ( A 1 ) O P ( A 2 ) → A C C (A_1)OP(A_2)\rightarrow ACC (A1)OP(A2)→ACC 的操作。对于前两种操作, A 1 A_1 A1 或 A 2 A_2 A2 既代表源操作数的地址,又代表存放本次运算结果的地址,完成一条指令仍需要访问 4 次存储器。对于第三种操作,中间结果暂存于 ACC 中,它完成一条指令只需 3 次访存。
如果将一个操作数隐含在运算器的 ACC 中,则指令字中只需要给出一个地址码,构成一地址指令。
④ 一地址指令
该指令完成 ( A C C ) O P ( A 1 ) → A C C (ACC)OP(A_1)\rightarrow ACC (ACC)OP(A1)→ACC 的操作,ACC 既存放参与运算的操作数,有存放运算的中间结果,这样,完成一条一地址指令只需要两次访存。
⑤ 零地址指令
在指令系统中,还有一种指令可以无地址码,即所谓零地址指令。例如,空操作(NOP)、停机(HLT)这类指令只有操作码。而子程序返回(RET)、中断返回(IRET)这类指令没有地址码,其操作数的地址隐含在堆栈指针 SP 中。
指令字长
指令字长取决于操作码的长度、操作数地址的长度和操作数地址的个数。不同机器的指令字长是不同的。
早期的计算机指令字长、机器字长和存储字长均相等,因此访问某个存储单元,便可取出一条完整的数据。这种机器的指令字长是固定的,控制方式比较简单。
对着计算机的发展,计算机的指令字长也发生了很大的裱花,一台机器的指令系统可以采用位数不相同的指令,即指令字长是可变的,如单字长指令、多字长指令。