MIPS指令解码

MIPS Instruction Decoding

我正在尝试了解如何解码 MIPS 二进制指令。

我使用 gcc 在 Debian MIPS 系统上用 C 语言编译了一个 hello world 程序,objdump 显示 .text 部分中的第一条指令是:

600: 03e00025 move zero,ra

我不明白它是如何确定这是MOVE指令的。

03e00025 在二进制中是 00000011111000000000000000100101。如果我没看错,这里的前6位是操作码,在本例中全为0,表示它是R型指令,所以我们要看后6位,也就是100101。查看 MIPS Instruction Set Manual 看起来这应该是 OR 指令。我什至在那本手册中找不到 MOVE

谷歌搜索我发现汇编中显然有 "pseudo" 指令,并且据说 move $t, $s 扩展为 addiu $t, $s, 0,但如果我查看手册 ADDIU 有操作码 001001。我发现的另一个结果声称它转换为 ADDADD 的最后六位应该是 100000,所以这也不适合。

我错过了什么?

MIPS 机器代码没有 move 的特定操作码,但为了方便人类,许多 assemblers 支持伪指令,如 lila,而 move 即 assemble 为一条或多条真实机器指令。 addiu是普通的。

objdump 将指令解码为 or [=15=], $ra, [=15=](根据 Jester 的说法)以向您展示它的实际编码方式是完全正确的。

出于某些目的,disassembler 解码任何常用的将寄存器复制到 move 助记符的方法是有意义的。添加或 ORing 立即数 0,或读取 $zero 寄存器的零,对值不做任何操作,因此它被复制不变。

阅读asm时,你通常不关心它是ororiaddiu [=21=], $ra, 0还是其他什么。


不同的 assemblers 可能对 move 伪指令使用不同的实现,或者手写的 asm 可以使用它们中的任何一个。我认为这两种方式都不会对性能产生任何影响。所以具体使用哪条机器指令来实现一个move取决于assembler.


我不确定目的地为 $zeromove 有什么意义。那将是一个空操作,因为 $zero 丢弃写入。 (它是 CPU 寄存器等同于 /dev/zero