我在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)会提取最后的24位x,但是为什么他们需要第一部分((int)((x) >> 40) & ~0xFFF)呢?
至于
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 40) | ((x) & 0xFFF)) 我对((intpte_t)((x) & ~0xFFF) << 40)的目的感到迷茫。在我看来应该是0。那我们为什么需要它?
谢谢,
发布于 2013-12-31 18:09:12
我得看两遍他们的代码。因为我花了一分钟才意识到0xFFF不是24位,而是12位。以64位输入为例:0xAABBCCDDEEFF1122。把它右移40,你就可以得到0x0000000000AABBCC。在本例中,~0xFFF是0xFFFFFFFFFFFFF000的缩写。And他们在一起,你得到0x0000000000AAB000。所以基本上,他们抓住了前12位,然后把他们移下来。然后用下面的12位来表示or。所以他们最终得到了0x0000000000AAB122。
另一半则相反,在底部取24位,将其切成两半,将12位放在顶部,12位放在底部。
发布于 2013-12-31 18:06:32
0xFFF不是24位,只有12位。
知道了这一点,您将看到get_pte_flags的目的是将前12位移动到12-24位,如下所示:
xxxxxxxx xxxx0000 00000000 00000000 00000000 00000000 0000yyyy yyyyyyyy变成了
00000000 00000000 00000000 00000000 00000000 xxxxxxxx xxxxyyyy yyyyyyyy当然,put_pte_flags会做相反的操作,将位移回最重要的位置。
发布于 2013-12-31 17:58:59
想想64点。
当然,在32位系统上,结果是0。但是,当你把剩下的24位40位移开,你就有了
xxxxxxxx yyyyyyyy zzzzzzzz 00000000 00000000 00000000 00000000 00000000它是一个有效的64位值。
https://stackoverflow.com/questions/20861382
复制相似问题