【问题标题】:MIPS multu overflowMIPS 多溢出
【发布时间】:2018-11-18 04:51:26
【问题描述】:

作为十六进制转十进制程序的一部分,我使用 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 中。关于如何修复此代码以存储正确值的任何想法?

【问题讨论】:

    标签: mips qtspim


    【解决方案1】:

    multuunsigned 版本的mult,这意味着它不会生成overflow,因为结果被视为无符号数。当您通过syscall 显示值时,它被视为signed 数字,因此会显示带符号的值(在这种情况下为负数)。

    您没有提供有关您要达到的目标的太多信息,但是如果您要执行有符号乘法(意味着您希望保留结果的符号)并将结果存储在 32 位寄存器中,那么您将遇到限制。如果是这种情况,您需要在打印结果之前检查是否可以在这些范围内执行操作,这意味着您必须检查是否发生溢出:

     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:
     ....
    

    上述解决方案对最左边的位(通过右移 31 位获得)进行检查,该位表示符号(1 表示负数,0 表示正数)。如果一个且只有一个操作数是负数,那么结果应该是负数。如果两者都是负的或正的,那么结果应该是正的。我想你可以看到这两个异或是如何执行这个检查的。

    如果您想处理大于有符号数的最大大小的结果,那么您必须记住 mult 将结果的低部分存储在 LO 中,将结果的高部分存储在 @987654330 @。此时您将处理 64 位数字,每个数字占用两个字/寄存器。

    【讨论】:

      猜你喜欢
      • 2017-02-18
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多