x86 32-bit build (AT & T syntax):
/* int MaskedShiftByOne(int val, int lowest_bit_to_shift) */ mov 8(%esp), %ecx mov $1, %eax shl %ecx, %eax ; does 1 << lowest_bit_to_shift mov 4(%esp), %ecx dec %eax ; (1 << ...) - 1 == 0xf..f (lower bitmask) mov %eax, %edx not %edx ; complement - higher mask and %ecx, %edx ; higher bits and %ecx, %eax ; lower bits lea (%eax, %edx, 2), %eax ; low + 2 * high ret
This should work on both Linux and Windows.
Edit: i + (i & (~0 << x)) shorter:
mov 4(%esp), %ecx mov $-1, %eax mov 8(%esp), %edx shl %edx, %eax and %ecx, %eax add %ecx, %eax ret
Moral: Never start assembly. If you really need it, parse the highly optimized compiler output ...
source share