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

标签 assembly mips instruction-set risc

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

mul $t0 $s0 $s1

或这个:
mult $s0 $s1
mflo $t0

?

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

RISC 哲学说要经常使用伪指令,因为我们只有有限的真实指令。但我只是没有想到为什么你需要两种不同的乘法方式。两者都会影响 lohi (使用 MARS),因此您可以使用其中任何一个来检查溢出。那么为什么会出现冗余呢?为什么不告诉大家使用 mul每时每刻?

最佳答案

mul不是伪指令。它不会修改 hilo注册 mult做。它们是指令集中不同的真实指令。

一般来说,我们有 a = b * c
由于将两个 32 位数字相乘会产生 64 位结果,因此在一般情况下我们使用 mult然后用 mflo 得到结果的低 32 位高 32 位为 mfhi .这允许更高的准确性,但需要额外的指令 [或两条] 来获得结果。

如果我们只关心乘法结果的低 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

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

更新:

That's interesting. And you're right about it not being a pseudo-instruction. (You'd see that when it was assembled, if it were.) But when I use MARS, both mul and mult modify hi and lo. Maybe this is a MARS bug?



可能。 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 列为副作用。

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

作为一种好的做法,我可能不会依赖 lo/hi 在 mult 之后的有效时间过长。并且完全不依赖它们 mul ,所以,对于类作业,这有点争议。

看看 qemu 会很有趣做。它比 spim 更难使用或 mars [我更喜欢]但可能更接近实际硬件的功能。

关于assembly - 为什么在 MIPS 中有两种方法可以将任意有符号数相乘?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52748508/

相关文章:

code-generation - x86指令编码表

assembly - MIPS 十六进制输出

c - pic32 跳出引导加载程序导致一般异常

assembly - 指令集和指令集架构(ISA)有什么区别?

c++ - 合并两个可执行文件

c - 通过自修改代码进行动态混淆

c - 内联汇编程序 : What scratch registers can be used?

c - 在内核模式下将 KSEG2 与有线 TLB 一起使用

assembly - 我在哪里可以找到*所有* MIPS指令的描述

assembly - IBM 的 lis 和 ori 指令如何工作?