How To Check bits in C++?

Viewed 105

In C++ I wrote:

bool ret_is_syscall = (ret_inst_data & 0x00000000000000FF) == 0x000000000000050f;

but clion says it's always wrong, why?

I am trying to check if last 4 are 0x050f

2 Answers

Masking with 0xFF leaves only 8 bits available to look at, but 0x50f takes up 11 bits. So the comparison can never be true.

If you are only interested in the last 4 bits, use a mask of 0x0f instead:

bool ret_is_syscall = (ret_inst_data & 0x000000000000000f) == 0x000000000000000f;

Otherwise, you need a mask of at least 0x7FF (11 bits) in order to compare with 0x50f:

bool ret_is_syscall = (ret_inst_data & 0x00000000000007ff) == 0x000000000000050f;

If you are interested in the last 4 hex digits (16 bits), use a mask of 0xffff instead:

bool ret_is_syscall = (ret_inst_data & 0x000000000000ffff) == 0x000000000000050f;

If you want to check that the least-significant 2 bytes of ret_inst_data have exactly the value 0x050F, then you need to use a mask of 0xFFFF:

bool ret_is_syscall = (ret_inst_data & 0xFFFF) == 0x050F;

As for why your original comparison is incorrect, let's look at just the least-significant two bytes of the numbers involved.

  • 0x050F has the bit pattern 0000 0101 0000 1111
  • 0x00FF has the bit pattern 0000 0000 1111 1111

If we bitwise and those two patterns together, we get the bit pattern

  0000 0101 0000 1111
& 0000 0000 1111 1111
---------------------
  0000 0000 0000 1111

The binary 0000 0000 0000 1111 is 0x000F in hex.

As you can see, because the second-least-significant-byte of 0x00FF is all 0s, the result of performing a bitwise and between 0x00FF and any number will produce a result with a second-least-significant-byte of all 0s. Since the second-least-significant byte of 0x050F is not all 0s your comparison can never be true.

Related