Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 为什么在MIPS中有两种方法可以将任意有符号数相乘?_Assembly_Mips_Instruction Set_Risc - Fatal编程技术网

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

Assembly 为什么在MIPS中有两种方法可以将任意有符号数相乘?,assembly,mips,instruction-set,risc,Assembly,Mips,Instruction Set,Risc,如果需要将MIPS中的两个任意有符号数字相乘,是否有理由选择: mul $t0 $s0 $s1 或者这个: mult $s0 $s1 mflo $t0 ? 我在网上找到了不一致的答案,关于每个答案的含义。乍一看,我认为前者是后者的伪指令。(甚至有一个网页声称这一点。)但看看机器代码,似乎mult是一个有效的R型指令(操作码0),而mul有一个非零操作码(0x1c),因此不应该是R型,即使它包含3个寄存器 RISC的理念是经常使用伪指令,因为我们只有有限的真实指令。但我只是不想你为什么需要两种

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

mul $t0 $s0 $s1
或者这个:

mult $s0 $s1
mflo $t0
?

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

RISC的理念是经常使用伪指令,因为我们只有有限的真实指令。但我只是不想你为什么需要两种不同的方法来繁殖。这两种方法都会影响
lo
hi
(使用MARS),因此您可以使用其中一种方法检查溢出。那为什么要裁员呢?为什么不告诉大家一直使用
mul

mul
不是伪指令。它既不修改
hi
寄存器,也不修改
mult
寄存器。它们是指令集中不同的实际指令

一般来说,我们有
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
将[必须]在
mul
mult
行之间注入
mflo$v0


更新:


那很有趣。你说得对,这不是伪指令。(如果装配好的话,你会看到的。)但当我使用火星时,mul和mult都会修改hi和lo。也许这是火星虫

可能吧<代码>spim还修改hi和lo

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

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

公司[AFAICT]的ISA参考手册副本如下:

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

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

作为良好的实践,我可能不会在
mult
之后太长时间内依赖lo/hi有效,也不会在
mul
中依赖它们,因此,对于课堂作业来说,这有点没有意义


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

(在有人问我之前:我不是学生。我是一名试图理解和回避学生问题的教师。)“我在网上发现,关于每个问题的含义,答案不一致。”我建议按MIPS32的方法去做™ 程序员体系结构第二卷:MIPS32™ 在查看任何在线答案之前,说明集上都有说明。仅供参考purpose@phuclv:这是关于如何将知识传授给学生的问题。这个问题不属于这里,它是一个关于MIPS乘法指令的严格的技术问题,而不是关于如何教学生这些指令。(为什么不告诉大家一直使用mul?是关于混淆在线搜索结果,而不是关于如何教学生)这很有趣。你说得对,这不是伪指令。(如果装配好的话,你会看到的。)但当我使用火星时,mul和mult都会修改hi和lo。也许这是一个火星错误?这看起来类似于原始的MIPS(R2000)有一个乘法单元,它只是松散地连接到整数内核的其余部分。(见附件)。由于乘法(或除法)需要很多周期,而且他们希望整数寄存器的修改在5级流水线中的WB级完成,所以必须给出一些东西。具有读/写
lo/hi
的特殊指令,让
mult
超慢,除读取输入外,无需与正常寄存器文件交互。(在运行
mult
!)之后,在几个INSN内不允许修改这些MIPS)后来的MIPS可以在GP整数寄存器上互锁指令(并且具有更长的管道和更高的性能乘法单元)我们能够有效地引入一种新的乘法指令,它提高了代码密度,减少了
mflo
指令的开销。