将值存储在MIPS的HI和LO寄存器中

时间:2009-05-05 08:37:54

标签: assembly mips cpu-registers spim

我正在使用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注册表中存储内容?

3 个答案:

答案 0 :(得分:7)

我想延长Nils Pipenbrinck的回答:

来自程序员的MIPS32 arquitechture

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中。

限制: 在将新结果写入HI或LO之前,必须由MFHI或MFLO读取由DIV,DIVU,MULT或MULTU写入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,此限制不存在。

答案 1 :(得分: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注册表所涉及的延迟和危险。它们非常特殊,您的代码可能需要在写入和读取之间至少等待三个周期。不幸的是,这种行为取决于您正在使用的CPU。

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

答案 2 :(得分:1)

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