我在 xen 的内核代码(文件:xen/include/asm-x86/x86_64/page.h)中看到一行,但无法理解他们为什么这样做:
/* Extract flags into 24-bit integer, or turn 24-bit flags into a pte mask. */
#define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF))
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))
至于
#define get_pte_flags(x) (((int)((x) >> 40) & ~0xFFF) | ((int)(x) & 0xFFF))
我明白了((int)(x) & 0xFFF)
将提取 x 的最后 24 位,但为什么他们需要第一部分 ((int)((x) >> 40) & ~0xFFF)
?
至于
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF))
我迷失了 ((intpte_t)((x) & ~0xFFF) << 40)
的目的.在我看来应该是0。那我们为什么需要它?
谢谢,
最佳答案
我不得不仔细查看他们的代码。因为我花了一分钟才意识到 0xFFF 不是 24 位,它只是 12 位。因此,以 64 位输入为例:0xAABBCCDDEEFF1122
。将它右移 40,得到 0x0000000000AABBCC
。 ~0xFFF
在这种情况下是 0xFFFFFFFFFFFFFF000
的简写。 和
它们在一起,你得到0x0000000000AAB000
。所以基本上,他们捕获了前 12 位并将它们向下移动。然后他们 或
低 12 位。所以他们以 0x0000000000AAB122
结束。
另一半则相反,在底部取 24 位,将它们切成两半,然后将 12 位放在顶部,将 12 位放在底部。
关于c - 将标志提取为24位整数的位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20861382/