按位与的相反
The opposite of bitwise AND
我不喜欢那么多嵌套的 if,这就是为什么我想要那个条件的反义词 if (section_header[i].Characteristics & IMAGE_SCN_MEM_WRITE)
。那会是什么?我试过 if (section_header[i].Characteristics & ~IMAGE_SCN_MEM_WRITE) continue
,但它不正确。
for (WORD i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i)
{
if (functions[i] >= section_header[i].VirtualAddress && functions[i] < section_header[i].VirtualAddress + section_header[i].Misc.VirtualSize)
{
if (section_header[i].Characteristics & IMAGE_SCN_MEM_WRITE)
{
... next
}
}
}
翻转条件是减少“箭头代码”(大量缩进代码)的常见做法:
for (WORD i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i) {
if(!(section_header[i].VirtualAddress < functions[i] && functions[i] < section_header[i].VirtualAddress + section_header[i].Misc.VirtualSize)) {
continue;
}
if((section_header[i].Characteristics & IMAGE_SCN_MEM_WRITE) == 0) {
continue;
}
// From this point
// It's now guaranteed that selected function is in range and
// the selected section_header contains the IMAGE_SCN_MEM_WRITE bit
}
首先您需要确定'Characteristics'项目的类型。是uint32_t吗?这很重要,因为如果您尝试融合不兼容的类型,AND 操作可能会混淆。
我会这样做:
...
auto typed_flag = (uint32_t)IMAGE_SCN_MEM_WRITE;
if (((section_header[i].Characteristics bitand typed_flag) == typed_flag)
{
continue;
}
...
注意:'bitand' 比 & 符号更像 C++(尽管两者完全相同)。
如果您确定您的掩码只会设置一个位,那么您可以通过执行
来测试 value
中该位是否被清除(即未设置)
if (~value & MASK)
// bit is clear
但是,我不推荐这样做。 虽然逻辑上是正确的,但它比其他建议的选项 if (!(value & MASK))
或 if ((value & MASK) == 0)
更不惯用。阅读您的代码的人更容易产生误解,可能会导致他们通过“修复”它来制造新的错误。
此外,如果 MASK
应该设置多个位,则表达式 ~value & MASK
表达式将为真,如果 any 这些位被清除在 value
中,所以它不再是 value & MASK
的逻辑否定。例如,如果 MASK == 0x3
和 value == 0x2
,则 value & MASK
为真并且 ~value & MASK
也为真。相比之下,!(value & MASK)
为真当且仅当 所有 这些位都被清除。
我不喜欢那么多嵌套的 if,这就是为什么我想要那个条件的反义词 if (section_header[i].Characteristics & IMAGE_SCN_MEM_WRITE)
。那会是什么?我试过 if (section_header[i].Characteristics & ~IMAGE_SCN_MEM_WRITE) continue
,但它不正确。
for (WORD i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i)
{
if (functions[i] >= section_header[i].VirtualAddress && functions[i] < section_header[i].VirtualAddress + section_header[i].Misc.VirtualSize)
{
if (section_header[i].Characteristics & IMAGE_SCN_MEM_WRITE)
{
... next
}
}
}
翻转条件是减少“箭头代码”(大量缩进代码)的常见做法:
for (WORD i = 0; i < nt_headers->FileHeader.NumberOfSections; ++i) {
if(!(section_header[i].VirtualAddress < functions[i] && functions[i] < section_header[i].VirtualAddress + section_header[i].Misc.VirtualSize)) {
continue;
}
if((section_header[i].Characteristics & IMAGE_SCN_MEM_WRITE) == 0) {
continue;
}
// From this point
// It's now guaranteed that selected function is in range and
// the selected section_header contains the IMAGE_SCN_MEM_WRITE bit
}
首先您需要确定'Characteristics'项目的类型。是uint32_t吗?这很重要,因为如果您尝试融合不兼容的类型,AND 操作可能会混淆。
我会这样做:
...
auto typed_flag = (uint32_t)IMAGE_SCN_MEM_WRITE;
if (((section_header[i].Characteristics bitand typed_flag) == typed_flag)
{
continue;
}
...
注意:'bitand' 比 & 符号更像 C++(尽管两者完全相同)。
如果您确定您的掩码只会设置一个位,那么您可以通过执行
来测试value
中该位是否被清除(即未设置)
if (~value & MASK)
// bit is clear
但是,我不推荐这样做。 虽然逻辑上是正确的,但它比其他建议的选项 if (!(value & MASK))
或 if ((value & MASK) == 0)
更不惯用。阅读您的代码的人更容易产生误解,可能会导致他们通过“修复”它来制造新的错误。
此外,如果 MASK
应该设置多个位,则表达式 ~value & MASK
表达式将为真,如果 any 这些位被清除在 value
中,所以它不再是 value & MASK
的逻辑否定。例如,如果 MASK == 0x3
和 value == 0x2
,则 value & MASK
为真并且 ~value & MASK
也为真。相比之下,!(value & MASK)
为真当且仅当 所有 这些位都被清除。