Ada*_*ith 6 assembly mips instruction-set risc
如果您需要在 MIPS 中将两个任意有符号数相乘,是否有理由选择:
mul $t0 $s0 $s1
Run Code Online (Sandbox Code Playgroud)
或这个:
mult $s0 $s1
mflo $t0
Run Code Online (Sandbox Code Playgroud)
?
我在网上发现每个答案的含义不一致。乍一看,我认为前者是后者的伪指令。(甚至有一个网页声称这一点。)但是查看机器代码,它似乎是mult有效的 R 类型指令(操作码 0),而mul具有非零操作码(0x1c),因此不应该是 R 类型,即使它包含 3 个寄存器?!
RISC 哲学要求经常使用伪指令,因为我们只有有限的真实指令。但我只是没有想到为什么需要两种不同的乘法。两者都会影响lo和hi(使用 MARS),因此您可以检查其中任一是否溢出。那么为什么要裁员呢?mul为什么不直接告诉大家一直使用呢?
mul不是伪指令。它不会修改hi或lo寄存器mult。它们是指令集中不同的真实指令。
一般来说,我们有a = b * c
由于将两个 32 位数字相乘会产生 64 位结果,因此在一般情况下,我们使用mult,然后使用 得到结果的低 32 位mflo,并使用 得到结果的高 32 位mfhi。这允许更高的准确性,但代价是需要额外的指令[或两条]才能获得结果。
如果我们只关心乘法结果的低 32 位(例如数组索引计算),我们可以使用mul它允许结果与参数位于不同的寄存器中(在单个指令中)
考虑一个简单的程序:
.text
.globl main
main:
mul $v0,$a0,$a1
mult $v1,$a2
mflo $v0
Run Code Online (Sandbox Code Playgroud)
现在,如果我们使用 组装它mars,我们会得到:
00400000: 70851002 mul $v0,$a0,$a1
00400004: 00660018 mult $v1,$a2
00400008: 00001012 mflo $v0
Run Code Online (Sandbox Code Playgroud)
请注意,我们mflo在第 3 行有一条真正的指令。如果 mul是伪操作,mars则 [必须]在和行mflo $v0之间注入mulmult
更新:
那很有意思。你说得对,它不是伪指令。(如果是的话,你会在组装时看到这一点。)但是当我使用 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 列为副作用。
在我见过的一些文档中[我不记得是哪个],它指出[对于旧/真实硬件]您必须在 和multan之间有一个介入指令mflo(例如 a nop)。模拟器不需要这个。
作为良好的实践,我可能不会依赖低/高在太长时间后有效mult,并且根本不mul依赖它们,因此,对于课堂作业,这有点有争议。
看看会发生什么会很有趣qemu。spim它比或[我更喜欢]更难使用,mars但可能更接近实际硬件的功能。