你有什么简单的方法使MIPS寄存器中的值成为绝对值吗?
# 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
的每个位,否则保持不变。恰好反转一个数的所有位等同于将它设置为(-number)-1
(在二进制补码中)。$t0
最初为负数,则会得到:$t0 = ($t0 ^ 0xFFFFFFFF) - 0xFFFFFFFF
== (-$t0 - 1) - -1
== (-$t0 - 1) + 1
== -$t0
。$t0 = ($t0 ^ 0) - 0
== $t0
。这里有一个非常简单的方法来实现它。
#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
abs $t1, $t1
将寄存器$t1中的值取绝对值,并将其放入$t1中。
sra/xor/sub
序列。 - Myria bgtz $t0, label
label:
subu $t0, $zero, $t0
$t0
为正数,则否定$t0
的subu
指令将执行两次。您可能需要在汇编程序中启用.set noreorder
。最简单的方法就是对这些值进行一些二进制数学运算。
http://en.wikipedia.org/wiki/Signed_number_representations 描述了各种系统如何存储它们的负数。我相信MIPS使用“二进制补码”方案来存储有符号数。这使得它比位标志更难处理,但仍然可以做到。
movn
来在x
和-x
之间进行选择,就像clang为x86所做的那样。) - Peter Cordes