Related to Doing something in assembly vs having the assembler do it, I've tried my hand at checking the sign of a single number or multiple packed numbers, using the assembler to do much of the heavy lifting:
# Checking sign / unpacking values
# to check the sign, of an N-bit number, we can do check the left-most bit:
# 1 << (num_bits - 1)
# For example: for a signed 16 bit number, we can do:
# NUM & (1 << 15) --> if this is NOT ZERO, it means the left-most bit was set and thus is a negative (signed) number
# (1) checking a single number
NEG_NUM = -4
mov $NEG_NUM, %ax
test $(1 << (16-1)), %ax
setnz %r11b
POS_NUM = 4
mov $POS_NUM, %ax
test $(1 << (16-1)), %ax
setnz %r12b
# (2) checking multiple numbers packed into a single value
# pack two 16-bit values into %eax -- signed short nums[] = {10, -2}
NEG_MULTI_PART_NUM = 0x000AAFFE
mov $NEG_MULTI_PART_NUM, %eax
test $(1 << (32-1) | (1 << (16-1))), %eax
setnz %r13b
POS_MULTI_PART_NUM = 0x0B003F1E
mov $POS_MULTI_PART_NUM, %eax
test $(1 << (32-1) | (1 << (16-1))), %eax
setnz %r14b
I have a few questions related to this:
- Is
test $(1 << (numbits-1))
...setnz
the most common way to check if a signed number is negative? If not, what's a better way to do so? - To check the MSB in two packaged 2-byte values I'm doing
test $(1 << (32-1) | (1 << (16-1)))
. Again, does this seem like a good way to do this? Is the above considered unreadable, or is that clear enough?