c - 将标志提取为24位整数的位操作

标签 c linux-kernel

我在 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/

相关文章:

c - RGB565 格式的 ASCII 字符

c - 为什么使用 loff_t *offp 而不是直接使用 filp->f_pos 的原因

linux - Sync IO 在较新的 Linux 内核上慢得令人难以置信

c - Netlink 套接字创建返回 NULL

c - 如何在C中把帕斯卡三角形倒过来,让第一行最后打印,最后一行最先打印?

c - 艰难调试神秘的git+ssh+proxy失败 "bash: No such file or directory"

c - 输入带度数的数字

c - 二进制符号和字节顺序

c - Linux 内核 flush_write_buffers() 如何在 x86 上工作?

c - 如何在 Linux 上使用 Intel Westmere 1GB 页面?