在C语言中,我有一个32位的字表示一个地址(并且我已经将其存储在一个无符号长整型变量中,希望这没问题)。现在据我所知,地址的一部分包含页面号,另一部分包含偏移量。我想知道如何提取只给我页面号的位。我已经确定了前22个最重要的位是页面号,其他10个位是页面偏移量。我该如何获取仅为页面号的位?我认为我可以通过一些按位操作来实现,但不确定怎么做。
在C语言中,我有一个32位的字表示一个地址(并且我已经将其存储在一个无符号长整型变量中,希望这没问题)。现在据我所知,地址的一部分包含页面号,另一部分包含偏移量。我想知道如何提取只给我页面号的位。我已经确定了前22个最重要的位是页面号,其他10个位是页面偏移量。我该如何获取仅为页面号的位?我认为我可以通过一些按位操作来实现,但不确定怎么做。
使用位移运算符提取所需的位。
pageNumber = x >> 10;
offset = x & ((1 << 10) - 1);
对于页码,>> 运算符将位向下移动,因此您会丢失最低有效位。
对于偏移量,((1 << 10) - 1) 创建一个掩码,其中包含 10 个二进制的1,用于仅选择最低的 10 位并忽略最高位。
我非常喜欢“两个移位”的字段提取方法。它适用于有符号和无符号的数据类型。要从word
中提取宽度为w
,最低有效位为lsb
的字段:
#define BITSIN(W) (8*sizeof(W))
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width);
BITSIN(word) == 32
且lsb+width == 32
,因此只要所讨论的字是无符号的,你可以直接向右移10位而不需要进行掩码操作。x << y
将x
左移y % 32
个比特(前提是x
具有32位整数类型)。这意味着如果你尝试将一个32位整数左移或右移32位,结果就像没有操作一样。64位类型的64位移位也存在类似问题。