您是否有任何简单的方法可以将MIPS中的寄存器中的值作为绝对值?
答案 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
。