2010-02-22 103 views

回答

11

這是一個非常簡單的方法來做到這一點。

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

最簡單的方法只是對這些值做一些二進制數學運算。

http://en.wikipedia.org/wiki/Signed_number_representations描述了各種系統如何存儲其負數。我相信MIPS使用二進制補碼方案來存儲有符號數字。這使得它比標誌位更難一點,它可以通過將數字與0b01111111進行與運算來關閉,但它仍然可行。

17

這裏有一個分支少的變體:

# 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

警告:該方法由美國專利#6073150涵蓋。雖然可能無效,但因爲它的知名度超過了1997年。 – Myria 2015-08-08 00:47:51

8

最簡單的方法。 有一個僞指令,可以做這個:

abs $t1, $t1 

將採取值的絕對值在寄存器$ T1,並將其放置在$ T1

+1

這個僞指令是另一個答案中顯示的sra/xor/sub序列。 – Myria 2015-08-08 00:52:23

1

下面是它的尺寸優化版本。它比SRA/XOR /蘇布答案較慢,由於分支預測的問題,但它是一個指令較小:

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

這工作,因爲MIPS延遲槽的:如果$t0是正的,subu指令否定$t0執行兩次。您可能需要在彙編器中啓用.set noreorder