MIPS 汇编/指令格式
外观
本页介绍了 MIPS 指令格式的实现细节。
R 指令用于当指令使用的数据值全部位于寄存器中时。
所有 R 类指令都有以下格式
OP rd, rs, rt
其中 "OP" 是特定指令的助记符。所有 R 指令都使用操作码 0,函数位于 funct 字段。rs 和 rt 是源寄存器,rd 是目标寄存器。例如,add 助记符可以用于
add $s1, $s2, $s3
其中,$s2 和 $s3 中的值相加,结果存储在 $s1 中。在本指南的主要部分中,操作数将用这些名称表示。
将 R 助记符转换为等效的二进制机器码,可以使用以下方法执行
操作码 | rs | rt | rd | 移位 (shamt) | funct |
6 位 | 5 位 | 5 位 | 5 位 | 5 位 | 6 位 |
- 操作码
- 操作码是指令助记符的机器码表示。操作码字段长 6 位(第 26 位到第 31 位),但在 R 格式中始终设置为 0。要执行的实际指令位于 funct 字段中。
- rs, rt, rd
- 源寄存器和目标寄存器的数字表示。这些数字对应于寄存器的 $X 表示,例如 $0 或 $31。每个字段长 5 位。(分别为 25 到 21、20 到 16 和 15 到 11)。有趣的是,rs 和 rt 并没有被命名为 r1 和 r2(表示源寄存器 1 和 2),而是分别被命名为 "rs" 和 "rt",代表寄存器源、寄存器目标和寄存器目标。
- 移位 (shamt)
- 与移位和旋转指令一起使用,这是源操作数 rs 旋转/移位的量。此字段长 5 位(6 到 10)。
- Funct
- 在 R 格式指令中,操作码始终为零,funct 参数包含不同指令的代码。长 6 位(0 到 5)。例如,要将两个寄存器中的数字相加并将结果放入第三个寄存器中,操作码将设置为零,函数将设置为 0x20。
I 指令用于当指令必须对立即值和寄存器值进行操作时。立即值最多可以长 16 位。立即指令无法操作更大的数字。
I 指令以以下方式调用
OP rt, rs, IMM
但是,sw 和 lw 指令以以下方式调用
OP rt, IMM(rs)
其中,rt 是目标寄存器,rs 是源寄存器,IMM 是立即值。立即值最多可以长 16 位。例如,addi 指令可以调用为
addi $s1, $s2, 100
其中,$s2 的值加上 100 存储在 $s1 中。
I 指令以以下格式转换为机器码字
操作码 | rs | rt | IMM |
6 位 | 5 位 | 5 位 | 16 位 |
- 操作码
- 指令的 6 位操作码。在 I 指令中,所有助记符都与底层操作码有一对一对应关系。这是因为没有funct 参数来区分具有相同操作码的指令。6 位(26 到 31)
- rs, rt
- 分别为源寄存器和目标寄存器操作数。每个操作数 5 位(分别为 21 到 25 和 16 到 20)。[1]
- IMM
- 16 位立即值。16 位(0 到 15)。该值通常用作各种指令中的偏移值,并且根据指令,可能以二进制补码表示。
J 指令用于执行跳转时。J 指令对立即值有最多的空间,因为地址是较大的数字。
J 指令以以下方式调用
OP LABEL
其中,OP 是特定跳转指令的助记符,LABEL 是要跳转到的目标地址。
J 指令具有以下机器码格式
操作码 | 伪地址 |
6 位 | 26 位 |
- 操作码
- 对应于特定跳转命令的 6 位操作码。(26 到 31)。
- 地址
- 目标地址的 26 位缩短地址。(0 到 25)。完整的 32 位目标地址是通过连接 PC 的最高 4 位(紧随跳转指令后的指令地址)、26 位伪地址和 2 个零位(因为指令始终与 32 位字对齐)形成的。
FR 指令类似于上面描述的 R 指令,只是它们专用于浮点数。
操作码 | fmt | ft | fs | fd | funct |
FI 指令类似于上面描述的 I 指令,只是它们专用于浮点数。
操作码 | fmt | ft | Imm |
下表列出了 MIPS 指令和相应的操作码。操作码和函数编号均以十六进制表示。
助记符 | 含义 | 类型 | 操作码 | Funct |
---|---|---|---|---|
add |
加法 | R | 0x00 | 0x20 |
addi |
加法立即数 | I | 0x08 | NA |
addiu |
无符号加法立即数 | I | 0x09 | NA |
addu |
无符号加法 | R | 0x00 | 0x21 |
and |
按位与 | R | 0x00 | 0x24 |
andi |
按位与立即数 | I | 0x0C | NA |
beq |
如果相等则跳转 | I | 0x04 | NA |
blez |
如果小于或等于零则跳转 | I | 0x06 | NA |
bne |
如果不相等则跳转 | I | 0x05 | NA |
bgtz |
如果大于零则跳转 | I | 0x07 | NA |
div |
除法 | R | 0x00 | 0x1A |
divu |
无符号除法 | R | 0x00 | 0x1B |
j |
跳转到地址 | J | 0x02 | NA |
jal |
跳转并链接 | J | 0x03 | NA |
jalr |
跳转并链接寄存器 | R | 0x00 | 0x09 |
jr |
跳转到寄存器中的地址 | R | 0x00 | 0x08 |
lb |
加载字节 | I | 0x20 | NA |
lbu |
加载无符号字节 | I | 0x24 | NA |
lhu |
加载无符号半字 | I | 0x25 | NA |
lui |
加载高位立即数 | I | 0x0F | NA |
lw |
加载字 | I | 0x23 | NA |
mfhi |
从 HI 寄存器中移动 | R | 0x00 | 0x10 |
mthi |
移动到 HI 寄存器 | R | 0x00 | 0x11 |
mflo |
从 LO 寄存器中移动 | R | 0x00 | 0x12 |
mtlo |
移动到 LO 寄存器 | R | 0x00 | 0x13 |
mfc0 |
从协处理器 0 移动 | R | 0x10 | NA |
mult |
乘法 | R | 0x00 | 0x18 |
multu |
无符号乘法 | R | 0x00 | 0x19 |
nor |
按位非或 (NOT-OR) | R | 0x00 | 0x27 |
xor |
按位异或 (Exclusive-OR) | R | 0x00 | 0x26 |
or |
按位或 | R | 0x00 | 0x25 |
ori |
按位或立即数 | I | 0x0D | NA |
sb |
存储字节 | I | 0x28 | NA |
sh |
存储半字 | I | 0x29 | NA |
slt |
如果小于则设置为 1 | R | 0x00 | 0x2A |
slti |
如果小于立即数则设置为 1 | I | 0x0A | NA |
sltiu |
如果小于无符号立即数则设置为 1 | I | 0x0B | NA |
sltu |
如果小于无符号数则设置为 1 | R | 0x00 | 0x2B |
sll |
逻辑左移 | R | 0x00 | 0x00 |
srl |
逻辑右移(0 扩展) | R | 0x00 | 0x02 |
sra |
算术右移(符号扩展) | R | 0x00 | 0x03 |
sub |
减法 | R | 0x00 | 0x22 |
subu |
无符号减法 | R | 0x00 | 0x23 |
sw |
存储字 | I | 0x2B | NA |