如何在 C++ 中检查位?

问题描述

在 C++ 中我写道:

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

但是 clion 说它总是错的,为什么?

我正在尝试检查最后 4 个是否为 0x050f

解决方法

使用 0xFF 进行掩蔽只留下 8 位可供查看,但 0x50f 占用了 11 位。所以这种比较永远不会是真的。

如果您只对最后 4 个感兴趣,请改用 0x0f 掩码:

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

否则,您需要至少 0x7FF(11 位)的掩码才能与 0x50f 进行比较:

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

如果您对最后 4 个十六进制数字(16 位)感兴趣,请改用 0xffff 掩码:

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

如果要检查 ret_inst_data 的最低有效 2 个字节是否正好具有值 0x050F,则需要使用 0xFFFF 的掩码:

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

至于为什么您的原始比较不正确,让我们只看所涉及数字的最低有效两个字节。

  • 0x050F 具有位模式 0000 0101 0000 1111
  • 0x00FF 具有位模式 0000 0000 1111 1111

如果我们按位和这两个模式一起,我们得到位模式

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

二进制 0000 0000 0000 11110x000F 的十六进制。

如您所见,由于0x00FF的第二个最低有效字节都是0,因此在0x00FF和任何数字之间按位执行的结果将产生具有所有 0 的次低有效字节的结果。由于 0x050F 的次低有效字节并非全是 0,因此您的比较永远不会为真。