当 andi mips 指令可能是非法的

when the andi mips instruction can be illegal

mips 指令的格式 andi $a0, $a0, 0x9AE3 看起来是正确的。这是一个 I 类型格式 opcode rs rt immediate。为什么 mips 指令无效?

正如@Peter所说,如果常量太大而无法放入立即字段,汇编器将拒绝该行或将其转换为多条指令,这些指令在执行请求的操作的过程中构建一些常量.

然而,对于andi,立即数字段是 16 位,被视为 unsigned,这意味着我们得到一个0x0000-0xFFFF 的范围,而 0x9000 显然在该范围内。

现在,如果操作码是 addi,不同之处在于 对于 addi,相同的 16 位立即数字段被视为 signed,这意味着我们得到范围 0xFFFF8000-0x00007FFF,这里 0x9000 超出了该范围(因此汇编器将拒绝该行汇编代码,或者用 2(或更多)指令替换序列,因为它不能在一条指令中编码)。


附带说明一下,许多 MIPS 汇编程序都非常友好,它们会采用处理器不自然支持的“合理”指令和操作数,并将它们视为伪指令,而是由一系列多机器实现的代码说明。这在 MIPS 思想集中如此普遍,可以通过保留整个 CPU 寄存器($at/</code>)作为此类扩展的临时存储来证明。在 RISC V 中,这已经消失,只允许可以重用目标的伪指令,否则(人类)汇编程序员必须编写适当的代码序列(并且可能涉及识别空闲寄存器)。恕我直言,这是一件好事,b/c MIPS 汇编器隐藏了不应该隐藏在汇编中的东西——例如,将一些看似无害的指令转换为 3 指令序列,当这些指令出现在循环中时,经过一些思考,本来可以做得更好(如果汇编程序员没有得到汇编程序的“帮助”并且被提醒考虑硬件可以更直接地考虑的情况)。</p> <hr /> <p>我们还要注意,在 RISC V 中,所有立即数都进行了符号扩展,因此它们还删除了 <code>andiaddi 对立即数的不同处理。正如@Peter 还指出的那样,RISC V 立即数也更小,这两者都增加了程序员和编译器的工作量,但通过只需要一种硬件机制来扩大立即数(即符号扩展和无零扩展),从而提高了硬件效率),并通过更好地利用编码位(更多位用于操作码,以实现更长的指令集寿命和自定义指令集扩展)。