2017-04-10 39 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位,如果要将它们视为有符号或无符号,则取决于您。 –