为什么在MIPS中有两种方法可以将任意有符号数字相乘?



如果您需要在MIPS中将两个任意有符号数字相乘,是否有理由首选:

mul $t0 $s0 $s1

或者这个:

mult $s0 $s1
mflo $t0

我在网上发现关于每个含义的答案不一致。乍一看,我认为前者是后者的伪指令。(甚至还有一个网页声称这一点。但是从机器代码来看,mult似乎是一个有效的 R 类型指令(操作码 0(,而mul有一个非零操作码 (0x1c(,所以不应该是 R 类型,即使它包含 3 个寄存器?!

RISC哲学说要经常使用伪指令,因为我们只有有限的真实指令。但我只是没有想到为什么你需要两种不同的乘法。两者都会影响lohi(使用 MARS(,因此您可以使用其中之一检查溢出。那么为什么要裁员呢?为什么不告诉大家一直使用mul呢?

mul

不是伪指令。不会修改mult所做的hilo寄存器。它们是指令集中不同的真实指令。

一般来说,我们有a = b * c

由于将两个 32 位数字相乘会产生 64 位结果,因此在一般情况下,我们使用mult然后用mflo得到结果的低 32 位,用mfhi得到结果的高 32 位。这样可以提高准确性,但代价是需要额外的指令[或两个]才能获得结果。

如果我们只关心乘法结果的低 32 位(例如数组索引计算(,我们可以使用mul它允许结果与参数位于不同的寄存器中(在单个指令中(

考虑一个简单的程序:

.text
.globl  main
main:
mul     $v0,$a0,$a1
mult    $v1,$a2
mflo    $v0

现在,如果我们使用mars组装它 ,我们得到:

00400000:   70851002    mul     $v0,$a0,$a1
00400004:   00660018    mult    $v1,$a2
00400008:   00001012    mflo    $v0

请注意,我们在第 3 行有一个真实的mflo指令。如果mul是伪操作,mars[必须]在mulmult线之间注入mflo $v0


更新:

这很有趣。你说得对,这不是一个伪指令。(如果是的话,你会在组装时看到它。但是当我使用 MARS 时,mul 和 mult 都会修改 hi 和 lo。也许这是一个 MARS 错误?

可能。spim修改了 hi 和 lo。

经过进一步思考,考虑到原始mips CPU内核的时代(大约1985年(以及它们拥有的[极其]有限的门数,这似乎是合乎逻辑的。

但是,真正的mips核心今天仍然存在。该公司是"MIPS Technologies,Inc",截至2017年仍然存在。

该公司[AFAICT]的ISA参考手册在这里有一份副本:https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00086-2B-MIPS32BIS-AFP-6.06.pdf

在该文档中,mul指令没有将更改 hi 或 lo 列为副作用。

在我看过的一些文档中[我不记得是哪个],它指出[对于旧的/真实的硬件],您必须在multmflo之间有一个干预指令(例如nop(。模拟器不需要这个。

作为好的做法,我可能不会依赖 lo/hi 在mult后持续太久,也根本不依赖它们进行mul所以,对于课堂作业,这有点有争议。

看看qemu做什么会很有趣。它比spimmars(我更喜欢(更难使用,但可能更接近实际硬件的功能。

相关内容

  • 没有找到相关文章

最新更新