This is how the C library function abs() does it in assembly without branching:
abs(x) = (x XOR y) - y
where y = x >> 31 (assuming 32-bit input), and >> is arithmetic right shift operator.
Explanation of the above formula:
We want to generate 2's complement of negative x only.
y = 0xFFFFFFFF, if x is negative
0x00000000, if x is positive
So when x is positive x XOR 0x00000000 is equal to x . And when x is negative x XOR 0xFFFFFFFF is equal to 1's complement of x. Now we just need to add 1 to get its 2's complement which is what expression -y is doing . Because 0xFFFFFFFF is -1 in decimal.
Let's look at assembly generated for following code by gcc (4.6.3 on my machine):
C code:
main()
{
int x;
int output = abs(x);
}
gcc 4.6.3 generated assembly snippet (AT&T syntax), with my comments:
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
BONUS (from Hacker's Delight): If you have a fast multiply by +1 and -1, the following will give you abs(x) for 32-bit x:
((x >> 30) | 1) * x