作为十六进制到十进制程序的一部分,我正在使用QT spim在MIPS中编写代码,我将16 ^ 7(268435456)的值加载到通用寄存器中。然后,我将这个数字乘以1-15(取决于字符),将结果加到一个连续的总数中,然后将16 ^ 7除以16。
但是,我乘以268435456时遇到了我认为是溢出的问题。例如,代码
li $t0, 10
li $t1, 268435456
multu $t0, $t1
mflo $t2
li $v0, 10
syscall
哪个打算将268435456乘以10并将结果存储在$ t2存储区中-1610612736而不是2684354560。有关如何解决此代码以存储正确值的任何想法?
答案 0 :(得分:0)
multu
是unsigned
的{{1}}版本,这意味着它不会生成mult
,因为结果被视为无符号数字。通过overflow
显示值时,它被视为syscall
数字,因此显示了带符号的值(在这种情况下为负)。
关于要达到的目标,您没有提供太多信息,但是如果您要执行有符号乘法(意味着要保留结果的符号)并将结果存储在32位寄存器中,则您将遇到限制。如果是这种情况,您将需要检查是否可以在这些范围内进行操作,然后再打印结果,这意味着您必须检查是否发生了溢出:
signed
上面的代码执行的操作是检查最左边的位(通过向右移31位获得),该位指示符号(1表示负,0表示正)。如果只有一个操作数为负,则结果应为负。如果两者均为负或正,则结果应为正。我想您可以看到两个异或如何执行此检查。
如果要处理的结果大于有符号数的最大维,则必须记住 li $t0, 10
li $t1, 268435456
multu $t0, $t1
mflo $t2
li $t3, 31
srl $t0, $t0, $t3
srl $t1, $t1, $t3
srl $t2, $t2, $t3
xor $t0, $t0, $t1
xor $t0, $t0, $t2
bgtz $t0, noOperationRoutine
li $v0, 10
syscall
noOperationRoutine:
....
将结果的下半部分存储在mult
中,将较高的部分存储在LO
中放在HI
中。此时,您将要处理64位数字,每个数字占用两个字/寄存器,并且不容易处理。