2017-04-10 83 views
0

我正在使用SHL/SHR以將寄存器中的數字減半。它對於正數和負數都可以正常工作。然而,有些東西正在擾亂我對負數的看法。x86程序集 - 如何使用SHR將負數有效減半?

我去之前,我應該說我知道的SARSAL轉移符號二進制,但我需要使用SHL/SHR明確。 (我嘗試了SARSAL和那些工作很好 - 但我不能使用那些)

所以就這個問題。

如果我有一個數字,讓我們說-5,這是存儲在寄存器中的「FFFFFFFB」。

但是,當我SHR它(將它減半)它被視爲如果它是4,294,967,291。它仍然適用於我的目的,但不是減半(這將需要3個循環來達到0),它將這個龐大的數字減半,並且取代更多的循環(32個循環)。這讓我感到非常低效。有沒有把它看成是-5而不是4,294,967,291的技巧?

我正在考慮檢查數字是否爲負值,並將其存儲在寄存器中。做它的工作,如果它是積極的,然後檢查我的neg/pos寄存器並相應地分配標誌?

但是這種方法聽起來不合適嗎?
但是,我又是新來的彙編,並不真正知道這是我希望爲這種類型的問題做的事情?

+5

如果你知道'sar',那麼你知道它做了什麼。所以,用'shr'和其他東西來模擬它。 PS:你的意見也會起作用。不要指望任何「有效」的東西,因爲有效的(高效的)方法是'sar'。 – Jester

+0

請注意,這個移位除法對值-1不正確(sar -1 == -1,不爲零)。否則'sar'就是最好的解決方案。如果你不能使用'sar',只能使用其他指令,那麼你應該研究'sar'做什麼,並用其他指令來模擬它。 – Ped7g

回答

1

當你懷疑,你必須記住的符號位:

MOV EAX,[TheValue] 
MOV EDX,EAX 
AND EDX,0x80000000 ; remember sign bit from EAX 
SHR EAX,1 
OR EAX,EDX   ; and put it back 

這將適當減半正反兩方面的值。結果在EAX中。

+0

好奇爲什麼問題在那裏擺在首位。爲什麼右移也會改變符號位和副作用,使其成爲一個巨大的正數?它不是唯一的目的(存儲標誌)在什麼情況下將其移出位置有用嗎? – Duxa

+0

符號位是最高位,在這種情況下是32位值。如果你想把這個值看作無符號的,那麼最高位就是最高位,而不是符號位。這是關於補碼的好處。通過右移一次,無符號值0x80000000可以減半:0x40000000。在彙編程序中,32位是32位,如果要將它們視爲有符號或無符號,則取決於您。 –