1

我试图了解如何解码 MIPS 二进制指令。

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

600: 03e00025 move zero,ra

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

03e0002500000011111000000000000000100101二进制的。如果我理解正确,这里的前 6 位是操作码,在这种情况下全为 0,这意味着它是 R 型指令,所以我们必须查看最后 6 位,即100101. 查看MIPS 指令集手册,它看起来应该是OR指令。MOVE我什至在那个手册里都找不到。

对此进行谷歌搜索,我发现程序集中显然有“伪”指令,并且应该move $t, $s扩展为addiu $t, $s, 0,但如果我查看手册ADDIU有 opcode 001001。我发现的另一个结果声称它转换为ADD但最后六位ADD应该是100000,所以这也不适合。

我错过了什么?

4

1 回答 1

2

MIPS 机器代码没有针对 的特定操作码move,但为了方便人类,许多汇编程序支持伪指令,如lilamove,它们可以组装成一条或多条真实机器指令。 addiu是一个常见的。

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

move出于某些目的,反汇编程序对任何常用的将寄存器复制到助记符的方法进行解码都是有意义的。从读取寄存器中添加或 ORing 立即0数或零$zero,对值不做任何事情,因此它被原封不动地复制。

阅读 asm 时,您通常不在乎它是or, ori,addiu $0, $ra, 0还是其他。


不同的汇编器可能对伪指令使用不同的实现move,或者手写 asm 可以使用其中的任何一个。我认为这两种方式都不会对性能产生任何影响。因此,使用哪条机器指令来实现 a 的细节move取决于汇编器。


我不确定move带有目的地的 a 的意义$zero是什么。那将是无操作的,因为$zero丢弃了写入。(它相当于 的 CPU 寄存器/dev/zero

于 2018-11-24T00:08:34.220 回答