提取位

发布于 2024-08-12 14:44:11 字数 169 浏览 11 评论 0原文

在C中, 我有一个代表地址的 32 位字(我将它存储在无符号长整型中,希望没问题)。现在,根据我收集的信息,地址的一部分包含页码,另一部分包含偏移量。我想知道如何提取给我页码的位。我已经计算出前 22 位最高有效位是页号,其他 10 位是页偏移量。如何只获取页码位?我想我可以通过一些按位运算来做到这一点,但不知道如何做。

In C,
I have a 32-bit word representing an address (and I have it stored in an unsigned long, hope that's ok). Now from what I gather, part of an address contains the page number and the other part contains the offset. I was wondering how I could extract just the bits that give me the page number. I have already worked out the first 22 most significant bits are the page number and the other 10 bits are the page offset. How can I grab just the bits that are the page number? I am thinking I can do this with some bitwise operations, but am not sure how.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

妄想挽回 2024-08-19 14:44:11

使用 bitshift 运算符提取您需要的位需要。

pageNumber = x >> 10;
offset = x & ((1 << 10) - 1);

对于页码,>>运算符向下移动位,因此您会丢失最低有效位。

对于偏移量,((1 << 10) - 1) 创建一个由 10 个 1 组成的位掩码,用于仅选择 10 个最低有效位并忽略最高有效位。

Use the bitshift operators to extract the bits you need.

pageNumber = x >> 10;
offset = x & ((1 << 10) - 1);

For the page number, the >> operator shifts bits down, so you lose the least signifcant bits.

For the offset, ((1 << 10) - 1) creates a bitmask consisting of 10 ones which is used to select only the 10 least significant bits and ignore the most significant bits.

末骤雨初歇 2024-08-19 14:44:11

我非常喜欢“两班倒”字段提取方法。它可以在签名和未签名的情况下工作。要从 word 中提取宽度为 w 且最低有效位 lsb 的字段:

#define BITSIN(W) (8*sizeof(W))
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width);

在本例中,BITSIN(word) == 32lsb+width == 32,因此只要相关单词是无符号的,您就可以直接右移 10 而无需屏蔽。

需要注意的是:小心 32 位类型上的 32 位移位! C 标准允许编译器做任何事情,而常见的 Intel 芯片所做的事情是没有用的:x << yx 左移 y % 32 位(前提是 x 具有 32 位整数类型)。这意味着如果您尝试将 32 位整数左移或右移 32 位,结果与无操作相同。 64 位类型的 64 位移位也存在类似的问题。

I'm a huge fan of the "two shifts" method of field extraction. It works both signed and unsigned. To extract a field of width w with least significant bit lsb from word:

#define BITSIN(W) (8*sizeof(W))
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width);

In this case, BITSIN(word) == 32 and lsb+width == 32, so as long as the word in question is unsigned, you can just shift right 10 without masking.

One caution: beware 32-bit shifts on 32-bit types! The C standard lets the compiler do anything, and what the common Intel chips do is not useful: x << y shifts x left by y % 32 bits (provided x has a 32-bit integer type). This means if you try to shift a 32-bit integer left or right by 32 bits, the result is the same as a no-op. There is a similar issue with 64-bit shifts of 64-bit types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文