代码之家  ›  专栏  ›  技术社区  ›  TJream

MIPS中使用addu检测溢出

  •  0
  • TJream  · 技术社区  · 1 年前

    我很难在MIPS中实现检测溢出并使用addu抛出错误。

    这是学校的作业。我们得到的代码是一个非常基本的银行分类账。分类账要求用户输入,如果是正数,则添加到余额中,如果是负数,则从余额中减去。我已经改进了它,可以根据分配检测非整数输入,现在我需要能够检测溢出并抛出错误消息,如果检测到溢出,则不更改余额(然后重新提示事务)。我在这里想,因为这只是加法,如果符号相同,结果是相反的符号,那么就有溢出。我还认为,如果迹象相反,那么就不应该发生溢出。

    目前,它似乎跳过了我的溢出检测,所以它可以工作,但没有检测到我需要的溢出。关于我做错了什么有什么建议吗?

    以下是我的代码的相关部分:

    loopB:
        li  $s1, 0          #### reset $s1
        add $s1, $zero, $t3     #### load integer value into $s1
        beqz    $s1, done       # If $s1 equals zero, branch to done
        li  $s2, 0          #### initialize $s2 for temporary balance
        addu    $s2, $s0, $t6       #### set temporary balance to initial balance
        addu    $s2, $s0, $s1       # add transaction amount to the temporary Balance
    
    oTest:
        sltiu   $t6, $s0, 0     #### if $t6 == 1 then number is negative
        sltiu   $t7, $s1, 0     #### if $t7 == 1 then number is negative
        
        bne $t6, $t7, LoopC     #### if opposite signs then no overflow
        
        sltiu   $t8, $s2, 0     #### if $t8 == 1 then the number is negative
        
        and $t9, $t6, $t7       #### if $t9 == 1 then $t6 and $t7 are both negative
        
        bne     $t9, $t8, over      #### if $t9 and $t8 are not both negative, then overflow has occured
        
        sgtu    $t6, $s0, $zero     #### if $t6 == 1 then number is positive
        sgtu    $t7, $s0, $zero     #### if $t7 == 1 then number is positive
        sgtu    $t8, $s0, $zero     #### if $t8 == 1 then number is positive
        
        and $t9, $t6, $t7       #### if $t9 == 1 then $t6 and $t7 are both positive
        
        bne $t9, $t8, over      #### if $t8 and $t9 are not equal then overflow has occured
    
    LoopC:
        addu    $s0, $s0, $s1       #### add transaction to balance
        li  $v0, 4          # system call code for print_string
        la  $a0, tabs       # load address of tabs into $a0
        syscall             # used to space over to the Balance column
        
        li  $v0, 1          # system call code for print_integer
        move    $a0, $s0        # move Bank Balance value to $a0 
        syscall             # print Bank Balance
        
        b   loop            # branch to loop
        
    over:
        li  $v0, 4          #### system call code for print_string
        la  $a0, oMsg       #### load address of msg. into $a0
        syscall             #### print the string
        
        li  $s2, 0          #### reset $s2
        
        li  $v0, 1          #### system call code for print_integer
        move    $a0, $s0        #### move Bank Balance value to $a0 
        syscall             #### print Bank Balance
        
        b   loop            # branch to loop
    
    1 回复  |  直到 1 年前
        1
  •  0
  •   Erik Eidt    1 年前

    你能解释一下你想在这里做什么吗

        addu    $s2, $s0, $t6       #### set temporary balance to initial balance
        addu    $s2, $s0, $s1       # add transaction amount to the temporary Balance
    

    ?

    这两条指示放在一起没有意义。第二次擦除/重置 $s2 而不使用第一个的结果。


    根据无符号数的定义,由于无符号数都不小于零,因此使用的无符号比较小于的值与0的立即数总是会产生false。换句话说,负数对于无符号数字来说是不可能的。

    如果您想知道数字是否为负数,请使用 签名的 而是进行比较。

    仅供参考,你也可以使用移位来提取或复制符号位,所以通过使用算术移位31,得到-1或0,通过使用逻辑移位31,获得1或0。


    从根本上讲,你处理的是有符号整数,所以所有的比较操作都应该有符号,除非你真的知道一些不同的东西。

    然而 你说得对 需要进行无符号加法和/或减法 以避免处理器的自动签名溢出检测 ,因为如果你点击它,它将终止你的程序。当没有溢出时,无符号加法将产生与有符号加法相同的数字、相同的数值、相同的位模式,因此,这是有效的。如果有溢出,你可以在想的时候检测到,例如在添加之后。

    但是,为了有意义,需要使用有符号算术进行比较,而且,这些有符号比较(与有符号加法/减法不同)不会有碰到处理器溢出陷阱的风险。