Skip to content

05 Representing Instructions in the Computer

指令在计算机中的表示和数字一样,程序也存储在内存中,和数据一样,可以读写,这也是存储程序(stored-program)这个术语的由来。

RISC-V 的指令长度也是 32 位,其布局称为指令格式(instruction format)。与汇编有所区别,这些指令称为机器语言(machine language),一系列指令称为机器码(machine code)。

RISC-V Fields

  • opcode 指令的基本操作,这个缩写是传统名。
  • rd 操作的目标寄存器,从中获取操作的结果。
  • funct3 opcode 的附加信息。
  • rs1 源操作数的第一个寄存器。
  • rs2 源操作数的第二个寄存器。
  • funct7 opcide 的附加信息。

这里有一个问题。对于 load 指令而言,源操作数的第二个值是常数,如何只有 5 位,最多只能是 31,这对于数组或者结构体的偏移量而言太小了。

这和统一的指令格式冲突,故而引出了第三个设计原则:

Design Principle 3: Good design demands good compromises.

设计原则 3:好的设计需要好的折中。

RISC-V 这里选择所有的指令长度一样,但是对于不同的指令有不同的格式。比如上面的格式称为 R 类型(R-type (for register)),下面的格式称为 I 类型(I-type),通常用于需要一个常量的指令,比如 addi

12 位的立即数,表示的范围是 ,对于 load 指令而言最大支持 2048 个字节,即 256 个字。如果寄存器个数多于 32 个,那么 rd 和 rs1 就需要更多 bit,那么立即数的范围就会小很多。

对于 store,我们也需要一个新的格式,因为其有两个源操作寄存器和一个常量。S 类型(S-type)指令个数如下。

这里立即数被分层了两个部分。这么做的目的是使得 rs1 和 rs2 两个位置和其他指令保持一致。第四章会阐述这个划分简化了硬件设计。使指令格式尽可能相似能够简化硬件设计。这里 opcode 和 funct3 的位置始终不变,长度也不变。

每个指令的 opcode 是唯一的,所以硬件能够知道指令的类型,进而处理各个部分。

保持所有指令拥有相同的大小和希望尽可能多的寄存器矛盾。更多的寄存器意味着使用更多的指令位。基于这些限制和越小越快的原则,大分部指令都有 16 或 32 个通用寄存器。