【问题标题】:Storing values in HI and LO registers of MIPS在 MIPS 的 HI 和 LO 寄存器中存储值
【发布时间】:2009-05-05 08:37:54
【问题描述】:

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

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

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

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

【问题讨论】:

  • 32 位(8 字节)。呃,32b 是 4 个字节,而不是 8 个。在 32 位 MIPS 上,HI 和 LO 都是 4 个字节。这是 8 个字节的对的 64 位串联(不适合任何单个寄存器)。

标签: assembly mips cpu-registers spim


【解决方案1】:

我想扩展 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 之前。 如果在这些算术指令之一之后执行 MTHI 指令,但在 MFLO 或 MFHI 之前 指令,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,此限制不存在。

【讨论】:

    【解决方案2】:

    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 程序员来说,这个错误是一个常见的陷阱 :-)

    【讨论】:

    • 谢谢,这确实是我忽略了。
    【解决方案3】:

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

    【讨论】:

    • 不要认为使用 multu 和 divu 可以将值存储在 HI/LO 寄存器中,因为除非非常小心,否则每条指令都会完全覆盖这两个寄存器:( 该死的 MIPS。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多