【问题标题】:when the andi mips instruction can be illegal当 andi mips 指令可能是非法的
【发布时间】:2021-06-14 21:21:41
【问题描述】:

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

【问题讨论】:

  • 有效和合法的。 clang -target mips -c foo.s 组装得很好;我检查了是否有我遗漏的东西。该常数可以用 16 位零扩展立即数表示(与 RISC-V 不同),这些是合法的 MIPS 寄存器。如果您有理由认为不是,请提供详细信息(minimal reproducible example)。你试过用 MIPS16 模式(压缩指令)组装它吗?
  • 我正在阅读一篇论文,这是唯一的信息。然后它问为什么不是一个有效的 MIPS 指令?我不是专家,但正如我所说,它看起来是正确的。
  • 什么纸?它有网址吗?汇编器将其组装成单个机器指令以用于真正的 MIPS 的事实使问题成为问题(基于错误的前提)。未来的读者可以检查自己。但是询问特定书籍或论文中的错误可能是相关的。 (或者他们可能在谈论一种修改后的 MIPS,它的工作方式不同,而不是真正的 MIPS。许多学生项目和东西使用简化的 MIPS,但与真正的商业 MIPS ISA 的兼容性有所不同,所以这是具体说明什么 MIPS 的另一个原因。 )

标签: assembly mips instructions


【解决方案1】:

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

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

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


附带说明,许多 MIPS 汇编程序非常友好,它们会采用处理器不自然支持的“明智”指令和操作数,并将它们视为伪指令,而是由一系列多条机器代码指令实现.这在 MIPS 思维模式中非常普遍,可以通过保留整个 CPU 寄存器 ($at/$1) 作为此类扩展的临时存储来证明这一点。在 RISC V 中,这已经消失了,只允许可以重用目标的伪指令,否则(人类)汇编程序员必须编写适当的代码序列(这可能涉及识别空闲寄存器)。恕我直言,这是一件好事,b/c MIPS 汇编器隐藏了不应该隐藏在汇编中的东西——例如,将一些看似无辜的指令转换为 3 指令序列,当这些指令发生在循环中时,一些认为,本来可以做得更好(如果汇编程序员没有得到汇编程序的“帮助”,并被提醒考虑硬件可以更直接地考虑这种情况)。


我们还要注意,在 RISC V 中,所有立即数都是符号扩展的,因此它们还删除了 andiaddi 对立即数的不同处理。正如@Peter 还指出的那样,RISC V 立即数也更小,这两者都增加了程序员和编译器的工作量,但是通过只需要一种硬件机制来扩大立即数(即符号扩展而不是零扩展)使硬件更高效),并通过更好地利用编码位(更多位用于操作码、更长的指令集寿命和自定义指令集扩展)。

【讨论】:

  • 哦,对了,RISC-V I 型指令也有一个更窄的立即数。所以这是另一种排除方式。我想知道 OP 是否可能有某种简化的自制 MIPS,可以像 RISC-V 那样对它的所有立即数进行符号扩展。或者至少更改andi,如果不是ori / xori,因为p & -16 或任何便于对齐的东西,但MIPS 不能在一条指令中完成。
猜你喜欢
  • 1970-01-01
  • 2020-04-30
  • 1970-01-01
  • 2014-07-18
  • 1970-01-01
  • 2019-01-21
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多