MIPS中的绝对值

时间:2010-02-22 16:55:52

标签: assembly mips

您是否有任何简单的方法可以将MIPS中的寄存器中的值作为绝对值?

5 个答案:

答案 0 :(得分:18)

这是一个无分支变体:

# 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。

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

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

因此,如果$t0原来是否定的,你会得到:
$t0 = ($t0 ^ 0xFFFFFFFF) - 0xFFFFFFFF == (-$t0 - 1) - -1 == (-$t0 - 1) + 1 == -$t0
如果它最初是积极的,你会得到:
$t0 = ($t0 ^ 0) - 0 == $t0

答案 1 :(得分:13)

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

#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

答案 2 :(得分:9)

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

abs $t1, $t1

将取寄存器$ t1中的值的绝对值并将其放在$ t1

答案 3 :(得分:1)

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

http://en.wikipedia.org/wiki/Signed_number_representations描述了各种系统如何存储其负数。我相信MIPS使用二进制方案来存储已签名的数字。这使得它比位标志更难,可以通过使用0b01111111对数字进行AND运算来关闭它,但它仍然可行。

答案 4 :(得分:1)

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

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

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