将值存储在 MIPS 的 HI 和 LO 寄存器中
我正在 MIPS 中编写某些代码,并且要求将结果临时存储在 HI
和 LO
特殊寄存器中(两者都是 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 个字节)中。
稍后,要从 HI
和 LO
寄存器检索结果,我可以:
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
寄存器中存储某些内容?
I am writing certain code in MIPS and I've come to the point where the requirement is to store the result, temporarily, in HI
and LO
special registers (both are 4 bytes wide). These instructions are at my disposal:
divu s,t lo <-- s div t ; hi <-- s mod t
multu s,t hi / lo < -- s * t ;
So, divu
stores result of division in LO
and remainder in HI
, while multu
stores result of multiplication in LO
(lower 4 bytes) and HI
(higher 4 bytes).
Later, to retrieve result from HI
and LO
registers, I can:
mfhi $v0
mflo $v1
I already figured out how to store result of a calculation in LO
:
ori $v0,$0,1 # Store result from $a0 into LO
divu $a0,$v0
- the
divu
stores result of the division in LO, so I just divide result by 1 to get it there.
However, storing in HI
is more complicated. One way would be to force multu
instruction to shift the value by 32 bits (4 bytes):
multu $a0,0x80000000 # Shift $a0 by 32 bits and store into HI/LO
But, the result is that the value in HI
is 1 bit right of where it should be (so if my value is 0100 1000
then HI
will contain 0010 0100
).
Does anyone know how to store something in HI
register?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想扩展 Nils Pipenbrinck 的答案:
From MIPS32 arquitechture for Programs
mthi
格式:MIPS32 (MIPS I)
目的:
将 GPR 复制到特殊用途 HI 寄存器
GPR rs 的内容被加载到特殊寄存器 HI 中。
限制:
由 DIV、DIVU、MULT 或 MULTU 写入 HI/LO 对的计算结果必须由 MFHI 或 MFLO 读取
在将新结果写入 HI 或 LO 之前。
如果在这些算术指令之一之后、MFLO 或 MFHI 之前执行 MTHI 指令
指令,LO 的内容是不可预测的。 以下示例显示了这种非法情况:
历史信息:
在 MIPS I-III 中,如果前面两条指令中的任何一条是 MFHI,则该 MFHI 的结果是不可预测的。
HI 或 LO 特殊寄存器的读取必须与写入它们的任何后续指令分开 2
或更多说明。 在MIPS IV及更高版本中,包括MIPS32和MIPS64,此限制不存在。
mtlo
格式:MIPS32 (MIPS I)
用途:
将 GPR 复制到特殊用途 LO 寄存器
说明:
将 GPR rs 的内容加载到特殊寄存器 LO 中。
限制:
由 DIV、DIVU、MULT 或 MULTU 写入 HI/LO 对的计算结果必须由 MFHI 或 MFLO 读取,然后才能将新结果写入 HI 或 LO。
如果在这些算术指令之一之后、MFLO 或 MFHI 指令之前执行 MTLO 指令,则 HI 的内容是不可预测的。
以下示例显示了这种非法情况:
历史信息:
在 MIPS I-III 中,如果前面两条指令中的任何一条是 MFHI,则该 MFHI 的结果是不可预测的。
HI 或 LO 特殊寄存器的读取必须与写入它们的任何后续指令分开 2
或更多说明。 在MIPS IV及更高版本中,包括MIPS32和MIPS64,此限制不存在。
I'd like to extend Nils Pipenbrinck answer:
From MIPS32 arquitechture for programmers
mthi
Format: MIPS32 (MIPS I)
Purpose:
To copy a GPR to the special purpose HI register
The contents of GPR rs are loaded into special register HI.
Restrictions:
A computed result written to the HI/LO pair by DIV, DIVU,MULT, or MULTU must be read by MFHI or MFLO
before a new result can be written into either HI or LO.
If an MTHI instruction is executed following one of these arithmetic instructions, but before an MFLO or MFHI
instruction, the contents of LO are UNPREDICTABLE. The following example shows this illegal situation:
Historical Information:
In MIPS I-III, if either of the two preceding instructions is MFHI, the result of that MFHI is UNPREDICTABLE.
Reads of the HI or LO special register must be separated from any subsequent instructions that write to them by two
or more instructions. In MIPS IV and later, including MIPS32 and MIPS64, this restriction does not exist.
mtlo
Format: MIPS32 (MIPS I)
Purpose:
To copy a GPR to the special purpose LO register
Description:
The contents of GPR rs are loaded into special register LO.
Restrictions:
A computed result written to the HI/LO pair by DIV, DIVU, MULT, or MULTU must be read by MFHI or MFLO before a new result can be written into either HI or LO.
If an MTLO instruction is executed following one of these arithmetic instructions, but before an MFLO or MFHI instruction, the contents of HI are UNPREDICTABLE.
The following example shows this illegal situation:
Historical Information:
In MIPS I-III, if either of the two preceding instructions is MFHI, the result of that MFHI is UNPREDICTABLE.
Reads of the HI or LO special register must be separated from any subsequent instructions that write to them by two
or more instructions. In MIPS IV and later, including MIPS32 and MIPS64, this restriction does not exist.
MIPS 指令集有 MFLO/MFHI 的对应指令集。
它称为 MTLO/MTHI,完全可以满足您的需求:
这些指令很少见,并且通常不会出现在汇总指令集参考中。
顺便说一句:请务必检查处理器手册,了解与 LO/HI 规则相关的延迟和危险。 它们非常特殊,您的代码可能必须在写入和读取之间等待至少三个周期。 不幸的是,这种行为取决于您所使用的 CPU。
对于有抱负的 MIPS 程序员来说,犯这个错误是一个常见的陷阱:-)
The MIPS instruction-set has a counterpart for MFLO/MFHI.
It's called MTLO/MTHI and does exactly what you want:
These instructions are rare and often not present in summarized instruction set references.
Btw: Be sure to check the processor manual about the latencies and hazards involved with the LO/HI regs. They are very special and your code may have to things like waiting at least three cycles between a write and a read. Unfortunately this behaviour depends on which CPU you're working on.
Getting this wrong is a common pitfall for aspiring MIPS programmers :-)
想想当用作 multu/divu 的第二个参数时,哪些其他极端值可能会产生有趣的结果(我故意含糊其辞,因为这看起来像一个家庭作业问题)。
Think about what other extreme values might produce interesting results when used as the second argument to multu/divu (I'm being intentionally vague because this looks like a homework question).