[英]Left Shift in C++ - Unexpected Result
問題: uint32_t entry = (uint16_t )1 << (bitPosition && 0xf);
我即將編寫一個 memory 分配器,它使用位 map 來跟蹤分配/空閑頁面。
void
PageAllocator::deallocate( uintptr_t memoryAddress )
{
logInfoEvent_m( "function = %s, file = %s, line = %i.",
__PRETTY_FUNCTION__,
__FILE__,
__LINE__
);
uint32_t pageNb = memoryAddress / memory::pageSize_c;
uint32_t index = pageNb / bitsPerBitmapEntry_c;
uint32_t bitPosition = pageNb % bitsPerBitmapEntry_c;
uint32_t entry = (uint32_t )1 << (bitPosition && 0x0f);
__pageAllocatorBitmap[index] = ((uint32_t )1 << (bitPosition && 0x0f));
logInfoEvent_m( " ____freeing page: address = 0x%*x; pageNb = %d; index = %d; bit position = %d; entry = %d; bit map entry 0x%*x.",
在初始化期間,為所有可用頁面調用 function。 我得到以下結果:
index = 1; bit position = 0; entry = 1; bit map entry 0x00000001.
但對於這一行,結果不正確:
index = 1; bit position = 5; entry = 2; bit map entry 0x00000002.
對於值為 0 的 position,結果是正確的。 對於 position 持有的任何其他值,條目的值為“2”,這是不正確的。 我對 position = 5 的期望是 entry = 32 decimal (0x20)。
環境:g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 GNU assembler (GNU Binutils for Ubuntu) 2.30
我一直在閱讀上一篇文章,但我在那里找到的所有提示都無助於解決問題。 我知道,超過 32 位的轉換是不可預測的。
任何線索我在這里做錯了什么。 很抱歉打擾了社區。
entry和__pageAllocatorBitmap[index]只能取值為 1 或 2,因為bitPosition && 0xf
是一個 boolean 表達式,取值為 0 或 1,因此您只能得到 1 ( 1 << 0
) 或 2 ( 1 << 1
)
您想根據bitPosition的低 4 位進行移動,因此只需替換
uint32_t entry = (uint32_t )1 << (bitPosition && 0xf); __pageAllocatorBitmap[index] = ((uint32_t )1 << (bitPosition && 0x0f));
經過
uint32_t entry = (uint32_t )1 << (bitPosition & 0xf);
__pageAllocatorBitmap[index] = ((uint32_t )1 << (bitPosition & 0x0f));
或者
uint32_t entry = (uint32_t )1 << (bitPosition & 0xf);
__pageAllocatorBitmap[index] = entry;
對不起那個愚蠢的錯誤!
但是,在提出的解決方案中,我的代碼在 QEMU 作為模擬器時崩潰了。
void
PageAllocator::deallocate( uintptr_t memoryAddress )
{
logInfoEvent_m( "function = %s, file = %s, line = %i.",
__PRETTY_FUNCTION__,
__FILE__,
__LINE__
);
uint32_t pageNb = memoryAddress / memory::pageSize_c;
uint32_t index = pageNb / bitsPerBitmapEntry_c;
uint8_t bitPosition = pageNb % bitsPerBitmapEntry_c;
uint32_t entry1 = (uint32_t )1 << 2;
uint32_t entry2 = (uint32_t )1 << 31;
//uint8_t shift = 2;
//uint32_t entry3 = (uint32_t )1 << (shift & 0x1f);
//__pageAllocatorBitmap[index] = ((uint32_t )1 << (bitPosition && 0x0f));
logInfoEvent_m( " ____freeing page: address = 0x%*x; pageNb = %d; index = %d; bit position = %d; entry1 = %d; entry2 = 0x%*x; bit map entry 0x%*x.",
16, memoryAddress,
pageNb,
index,
bitPosition,
entry1,
8, entry2,
//8, entry3,
8, __pageAllocatorBitmap[index]
);
使用 shift 語句中的固定值,結果是:
____ INFO: ____freeing page: address = 0x0000000001000000; pageNb = 8; index = 0; bit position = 8; entry1 = 4; entry2 = 0x80000000; bit map entry 0x00000000.
這是我所期待的。
但是,隨着變量的轉換,代碼只會崩潰:
void
PageAllocator::deallocate( uintptr_t memoryAddress )
{
logInfoEvent_m( "function = %s, file = %s, line = %i.",
__PRETTY_FUNCTION__,
__FILE__,
__LINE__
);
uint32_t pageNb = memoryAddress / memory::pageSize_c;
uint32_t index = pageNb / bitsPerBitmapEntry_c;
uint8_t bitPosition = pageNb % bitsPerBitmapEntry_c;
uint32_t entry1 = (uint32_t )1 << 2;
uint32_t entry2 = (uint32_t )1 << 31;
uint8_t shift = 2;
uint32_t entry3 = (uint32_t )1 << (shift & 0x1f);
與該 lst 語句 qemu 只是崩潰。
g++: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 GNU 匯編器 (GNU Binutils for Ubuntu) 2.30 qemu: qemu-system-x86_64
任何其他想法我做錯了什么? 感謝您的任何建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.