【问题标题】:Integer absolute value in MIPS?MIPS中的整数绝对值?
【发布时间】:2010-02-22 16:55:51
【问题描述】:

你有什么简单的方法可以在 MIPS 中将寄存器中的值设为绝对值吗?

【问题讨论】:

    标签: assembly mips absolute-value


    【解决方案1】:

    这是一个无分支的变体:

    # input and output in $t0
    sra $t1,$t0,31   
    xor $t0,$t0,$t1   
    sub $t0,$t0,$t1    
    

    这是如何工作的?
    首先,$t1$t0 的符号位填充。因此,如果$t0 为正,$t1 将设置为 0,如果$t0 为负,$t1 将设置为 0xFFFFFFFF。

    接下来,如果 $t1 为 0xFFFFFFFF,则 $t0 的每一位都被反转,如果 $t1 为 0,则保持不变。恰好反转一个数字的所有位与将其设置为 (-number)-1 相同(在二进制补码)。

    最后,从中间结果中减去 0xFFFFFFFF(等于 -1)或 0。

    所以如果 $t0 最初是负数,你会得到:
    $t0 = ($t0 ^ 0xFFFFFFFF) - 0xFFFFFFFF == (-$t0 - 1) - -1 == (-$t0 - 1) + 1 == -$t0
    如果它最初是肯定的,你会得到:
    $t0 = ($t0 ^ 0) - 0 == $t0

    【讨论】:

    • 警告:此方法受美国专利 #6073150 的保护。不过,可能是无效的,因为它的已知时间超过 1997 年。
    • @Myria:GCC 等编译器多年来一直在各种 ISA 上使用它。例如x86-64 的 GCC4.4:godbolt.org/z/Mv843o。 (还显示了 64 位 MIPS GCC5.4 使用条件移动 movn,在 x-x 之间进行选择,就像 clang 对 x86 所做的那样。)
    【解决方案2】:

    这是一个非常简单的方法。

    #assume you want the absolute value of r1
            ori $2, $zero, $1      #copy r1 into r2
            slt $3, $1, $zero      #is value < 0 ?
            beq $3, $zero, foobar  #if r1 is positive, skip next inst
            sub $2, $zero, $1      #r2 = 0 - r1
    foobar:
    #r2 now contains the absolute value of r1
    

    【讨论】:

    • 请注意,这是针对没有分支延迟槽的 MIPS,如 MARS / SPIM 默认模拟。否则,您需要将 move (ori) 重新排列到分支延迟槽中。
    【解决方案3】:

    最简单的方法。 有一个伪指令可以做到这一点:

    abs $t1, $t1
    

    将寄存器$t1中值的绝对值放入$t1中

    【讨论】:

    • 这个伪指令是另一个答案中显示的sra/xor/sub序列。
    【解决方案4】:

    这是它的尺寸优化版本。由于分支预测问题,它比 sra/xor/subu 答案慢,但它的指令更小:

        bgtz $t0, label
    label:
        subu $t0, $zero, $t0
    

    这是因为 MIPS 延迟槽而起作用的:如果 $t0 为正数,则用于否定 $t0subu 指令执行两次。您可能需要在您的汇编程序中启用.set noreorder

    【讨论】:

      【解决方案5】:

      最简单的方法就是对值进行一些二进制数学运算。

      http://en.wikipedia.org/wiki/Signed_number_representations 描述了各种系统如何存储它们的负数。我相信 MIPS 使用 二进制补码 方案来存储带符号的数字。这使得它比一个位标志更难,可以通过将数字与 0b01111111 进行与运算来关闭它,但它仍然是可行的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-17
        • 2018-05-07
        • 1970-01-01
        • 2014-01-31
        • 2012-08-16
        • 2016-05-17
        • 2021-06-30
        相关资源
        最近更新 更多