我需要得到2个有符号整数的差。 x86汇编语言中是否有ABS()函数,所以我可以这样做。任何帮助将不胜感激。
最佳答案
这是C库函数abs()
在汇编中不分支的方式:
abs(x) = (x XOR y) - y
其中
y = x >>> 31
(假定为32位输入),而>>>
是算术右移运算符。上述公式的解释:
我们只想生成负
x
的2的补码。y = 0xFFFF, if x is negative
0x0000, if x is positive
因此,当
x
为正时x XOR 0x0000
等于x
。当x
为负数时,x XOR 0xFFFF
等于x
的1的补码。现在我们只需要添加1
即可得到其2的补码,这就是-y
表达式的作用。因为0xFFFF
为十进制-1。让我们看一下
gcc
(在我的机器上为4.6.3)为以下代码生成的程序集:C代码:
main()
{
int x;
int output = abs(x);
}
gcc 4.6.3生成了程序集摘要(AT&T语法),并附有我的评论:
movl -8(%rbp), %eax # -8(%rbp) is memory for x on stack
sarl $31, %eax # shift arithmetic right: x >>> 31, eax now represents y
movl %eax, %edx #
xorl -8(%rbp), %edx # %edx = x XOR y
movl %edx, -4(%rbp) # -4(%rbp) is memory for output on stack
subl %eax, -4(%rbp) # (x XOR y) - y
奖励(来自Hacker's Delight):如果您将+1和-1快速相乘,则以下内容将为您提供
abs(x)
: ((x >>> 30) | 1) * x
关于assembly - x86汇编abs()实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2639173/