这些转变我错了吗?
Am I wrong with these shiftings?
我有一个带前导零的 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;
}
向左移动以清除数字是一个危险的游戏,在我看来,因为如果你碰巧使用 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
但是,正如雷米指出的那样,您可以只使用位字段 (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
我有一个带前导零的 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;
}
向左移动以清除数字是一个危险的游戏,在我看来,因为如果你碰巧使用 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
但是,正如雷米指出的那样,您可以只使用位字段 (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