MUL和MULU之间的确切差异
我从一个来源发现RS和RT的内容被认为是MUL的签名整数。
而对于Mulu,RS和RT的内容被认为是无符号整数。
但是,每次我执行MUL和MULU时,它们似乎都会产生相同的结果。
li $t0 -2
li $t1 2
mul $s0, $t0, $t1
mulu $s1, $t0, $t1
两家商店中的$ S0和$ S1商店。 我的问题是说RS和RT被认为是签名/未签名的整数以及MUL和MULU如何对待RT和RS的意思是什么? 我可以看到mul和mulu给出不同结果的具体情况是什么? 我正在使用火星模拟器。 谢谢。请问我是否有任何理解这个问题的困惑。
I have found from a source that contents of Rs and Rt are considered signed integers for mul.
Whereas, for mulu, contents of Rs and Rt are considered unsigned integers.
But every time I execute mul and mulu, they seem to give the same result.
li $t0 -2
li $t1 2
mul $s0, $t0, $t1
mulu $s1, $t0, $t1
Both stores -4 in $s0 and $s1.
My question is what is it mean by saying Rs and Rt are considered signed/unsigned integers and how mul and mulu are treating Rt and Rs differently?
What is the specific case for which I can see mul and mulu giving different result?
I am using MARS simulator.
Thank you. Please ask me if you have any confusion understanding the question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
MIPS具有一个提供确切答案的乘法单元:它需要32位×32位→64位,这是乘法的工作方式,从数学上讲。
在火星上,
mul
是一个真正的指令。 它产生的64位结果hi
&lo
,还将其占据低32位,并将其存储到rd
。 (该指令不是第一个MIP的一部分;稍后添加。) 如果执行此指令,您将看到hi
和lo
在火星中受到影响以及rd
。而火星上的
mulu
是伪指令。 它还产生一个64位结果,该结果hi
&lo
,并将其拿到低32位,并将其存储到“rd
”中(我在b/c上输入引号b/c此mulu
不是真实的指令,因此没有实际的寄存器字段),而是由火星汇编程序实现为2个真实说明:第一个multu rs,rt
,然后mflo rd
。 如果您在火星中查看此说明的机器代码,则将看到此扩展为2个说明,如果执行执行,您将首先看到hi
和lo
and 和然后受到影响的rd
。较旧的MIP仅通过两个操作数
多
&仅提供32×32→64结果。Multu
,并在SpecialHI
&中捕获的64位结果lo
寄存器(这样,乘法可以进行多个周期,而不会干扰可以并行运行的其他指令的整数寄存器文件),因此您可以考虑尝试使用这些说明t0,$ t1 和multu $ t0,$ t1
。在签名中完成的2×-2的答案(例如,使用
MULT
)为0xfffffffffff 0xfffffffffc,并且此值可以安全地将其截断为32位(或更少)(或更少),因为此值仅为-4,它是-4,它是-4适合少量的 1 。未签名中没有-2,因此这些位被解释为较大的正数,fffffffe 16 aka 4,294,967,294 10 。
在未签名中完成的2×0xfffffffe的答案(使用
multu
)为0x00000001 0xffffffffc,并且此值 - 正如您期望的无符号×unsigned所期望的那样是正面的 - 不适合32位不适合2 ,因此,当不做检查而无需检查时,我们就会有溢出,也就是说:一个错误的答案。碰巧的是,低32的位模式与签名&amp相同。未签名,但这是由于溢出而相对毫无意义的 - 当然,它对硬件很有用,因为这两个乘法类型都共享了很多电路。
1  我们怎么能分辨出32位的64位价值? 最高结果是所有0或全部1,这些位也与较低结果的标志位(顶部位,MSB)匹配。
我们将如何在MIPS上为此进行运行时间测试? 取下32位结果,然后将其算A右侧移动31位(仅留在LSB位置处的符号位)。 使用算术偏移将符号右移动时复制符号位,因此我们将根据原始符号获得全部0或全部1的值。  nbsp;然后将移位值与上部32位进行比较,如果相等,则可以在32位表示64位值,如果不相等,则不会适合32位。
2  我们怎么知道这个64位的数字不适合32位? 由于未签名的数据类型的所有位都是幅度位(即没有标志位),因此,如果结果的上部32位为非零,那么该数字需要超过32位来表示,并且仅保留低32位位会截断结果,就好像执行Modulo 2 32 一样。
MIPS has a multiplication unit that gives exact answers: it takes 32 bits × 32 bits → 64 bits, which is how multiplication works, mathematically speaking.
On MARS,
mul
is a real instruction. It produce a 64-bit result captured inhi
&lo
, and also takes the low 32 bits of that and stores it intord
. (This instruction was not part of the first MIPS; it was added later.) If you execute this instruction, you'll seehi
andlo
affected in MARS as well asrd
.Whereas on MARS
mulu
is a pseudo instruction. It also produces a 64-bit result captured inhi
&lo
, and takes the low 32 bits of that and stores it into "rd
" (which I put in quotes here b/c thismulu
is not a real instruction so does not have actual register fields), but is implemented by the MARS assembler as 2 real instructions as this: firstmultu rs,rt
, thenmflo rd
. If you look at the machine code for this instruction in MARS, you'll see this expansion into 2 instructions, and if you execute you'll first seehi
andlo
and then therd
being affected.Older MIPS offered only 32 × 32 → 64 results, via the two operand
mult
&multu
, with the 64-bit results captured in specialhi
&lo
register (this so that multiplication could take multiple cycles and not interfere with the integer register file that could be servicing other instructions running in parallel) so you might consider experimenting with those, e.g.mult $t0, $t1
, andmultu $t0, $t1
.The answer to 2 × -2 done in signed (e.g. using
mult
) is 0xffffffff 0xfffffffc, and this value can safely be truncated to 32 bits (or less), because this value is simply -4, which fits in the smaller number of bits1.There is no -2 in unsigned so those bits are interpreted as a large positive number, fffffffe16 aka 4,294,967,29410.
The answer to 2 × 0xfffffffe done in unsigned (using
multu
) is 0x00000001 0xfffffffc, and this value — which is positive as you'd expect for unsigned × unsigned — does not fit in 32 bits2, so when forcefully truncated without checking as you're doing, we have overflow, which is to say: a wrong answer.Happens that the bit pattern for the low 32 is the same as for signed & unsigned, but this is relatively meaningless due to the overflow — of course, it is useful for the hardware since this fact means the two multiplication types share much circuitry.
1 How can we tell this 64-bit value fits in 32 bits? The upper result is either all 0's or all 1's and those bits also match the sign bit (top bit, MSB) of the lower result.
How would we make a runtime test for this on MIPS? Take the lower 32 bit result and shift it arithmetically to the right by 31 positions (leaving only the sign bit in the LSB position). Using an arithmetic shift replicates the sign bit as it shifts right, so we will obtain a value that is either all 0's or all 1's according to the original sign. Then compare that shifted value with the upper 32 bits, and if equal, the 64-bit value can be represented in 32 bits, and if not equal then won't fit in 32 bits.
2 How do we know this 64-bit number won't fit in 32 bits? Since all the bits of an unsigned data type are magnitude bits (i.e. no sign bit), then if the upper 32 bits of the result is non-zero, then that number needs more than 32 bits to represent, and keeping only the low 32 bits will truncate the result as if doing modulo 232.