0

我有一个带前导零的 14 位地址,我想将它分成页码和偏移量。我试图通过移动地址来解决它,但我的偏移量得到了错误的值,但是页码显示正确。你能指出我在哪里错了吗?

页码位为 [2:5] 偏移位为 [6:15]

struct Mem
{
 unsigned int address = 0x0000;
 unsigned int pageNum = 0x0;
 unsigned int pageOff = 0x000;
}

int main()
{
 Mem box;

 box.address = 0x0ad0;
 box.pageNum = (box.address << 2) >> 12;
 box.pageOff = (box.address << 6) >> 6;

return 0;
}
4

1 回答 1

3

在我看来,左移清除数字是一种危险的游戏,因为如果你碰巧使用int而不是unsigned int,你可能会得到一个你不打算的符号扩展。我建议转移和掩盖:

如果您的地址如下所示:

X X P P P P O O O O O O O O O O

P页码和O偏移量在哪里,那么您将执行以下操作:

box.pageNum = (box.address >> 10) & 0xf; // 0xf is 1111 in binary, so it only keeps the right 4 binary digits
box.pageOff = box.address & 0x3ff; // 0x3ff is 1111111111 in binary, so it only keeps the right 10 digits

但是,正如 Remy 指出的那样,您可以只使用位字段(https://en.cppreference.com/w/c/language/bit_field),例如:

struct Address
{
    unsigned int offset : 10;
    unsigned int page_num : 4;
}

...

Address a;
a.page_num; // assign it directly
a.offset; // assign it directly
于 2021-04-01T20:21:44.380 回答