4

我正在 MIPS 中编写某些代码,我已经到了需要将结果临时存储在特殊寄存器(均为 4 字节宽)HI中的地步。LO这些说明可供我使用:

divu     s,t    lo <-- s div t ; hi <-- s mod t
multu    s,t    hi / lo < -- s * t ;

因此,divu将除法的结果LO和余数存储在 中HI,而multu将乘法的结果存储在LO(低 4 字节)和HI(高 4 字节)中。

稍后,要从寄存器中检索结果,我可以HILO

mfhi $v0
mflo $v1

我已经想出了如何将计算结果存储在LO

ori     $v0,$0,1            # Store result from $a0 into LO
divu    $a0,$v0
  • divu除法的结果存储在 LO 中,所以我只需将结果除以 1 即可。

但是,存储起来HI更复杂。一种方法是强制multu指令将值移动 32 位(4 字节):

multu    $a0,0x80000000     # Shift $a0 by 32 bits and store into HI/LO

但是,结果是 in 的值在HI它应该在的位置右边 1 位(所以如果我的值是,0100 1000那么HI将包含0010 0100)。

有谁知道如何在HI寄存器中存储一些东西?

4

3 回答 3

7

我想扩展 Nils Pipenbrinck 的答案:

来自面向程序员的 MIPS32 架构

mthi

格式:MIPS32 (MIPS I)

  MTHI rs

目的:将 GPR 复制到专用 HI 寄存器

Description: HI ← rs

GPR rs 的内容被加载到特殊寄存器 HI 中。

限制:

由 DIV、DIVU、MULT 或 MULTU 写入 HI/LO 对的计算结果必须由 MFHI 或 MFLO 读取,然后才能将新结果写入 HI 或 LO。如果在这些算术指令之一之后但在 MFLO 或 MFHI 指令之前执行 MTHI 指令,则 LO 的内容是不可预测的。以下示例显示了这种非法情况:

 MUL       r2,r4   # start operation that will eventually write to HI,LO
 ...               # code not containing mfhi or mflo
 MTHI      r6
 ...               # code not containing mflo
                   # this mflo would get an UNPREDICTABLE value
 MFLO      r3

历史资料:

在 MIPS I-III 中,如果前面两个指令中的任何一个是 MFHI,则该 MFHI 的结果是不可预测的。HI 或 LO 特殊寄存器的读取必须通过两条或更多条指令与写入它们的任何后续指令分开。在 MIPS IV 及更高版本中,包括 MIPS32 和 MIPS64,此限制不存在。

mtlo

格式:MIPS32 (MIPS I)

    MTLO rs

目的:将 GPR 复制到专用 LO 寄存器 说明:

 LO ← rs

GPR rs 的内容被加载到特殊寄存器 LO 中。

限制:由 DIV、DIVU、MULT 或 MULTU 写入 HI/LO 对的计算结果必须由 MFHI 或 MFLO 读取,然后才能将新结果写入 HI 或 LO。

如果在这些算术指令之一之后但在 MFLO 或 MFHI 指令之前执行 MTLO 指令,则 HI 的内容是不可预测的。以下示例显示了这种非法情况:

 MUL       r2,r4   # start operation that will eventually write to HI,LO
 ...               # code not containing mfhi or mflo
 MTLO      r6
 ...               # code not containing mfhi
                   # this mfhi would get an UNPREDICTABLE value
 MFHI      r3

历史资料:

在 MIPS I-III 中,如果前面两个指令中的任何一个是 MFHI,则该 MFHI 的结果是不可预测的。HI 或 LO 特殊寄存器的读取必须通过两条或更多条指令与写入它们的任何后续指令分开。在 MIPS IV 及更高版本中,包括 MIPS32 和 MIPS64,此限制不存在。

于 2009-05-05T11:49:58.517 回答
6

MIPS 指令集对应于 MFLO/MFHI。

它被称为 MTLO/MTHI,完全符合您的要求:

  mtlo $v0  # moves the contents of v0 into the lo-register
  mthi $v1  # moves the contents of v1 into the hi-register

这些指令很少见,并且通常不会出现在总结的指令集参考中。

顺便说一句:请务必查看处理器手册,了解与 LO/HI regs 相关的延迟和危险。它们非常特殊,您的代码可能不得不在写入和读取之间等待至少三个周期。不幸的是,这种行为取决于您正在使用的 CPU。

对于有抱负的 MIPS 程序员来说,犯这个错误是一个常见的陷阱 :-)

于 2009-05-05T10:31:22.853 回答
1

想想当用作 multu/divu 的第二个参数时,还有哪些其他极端值可能会产生有趣的结果(我故意含糊其辞,因为这看起来像是一个家庭作业问题)。

于 2009-05-05T10:30:51.047 回答