簡體   English   中英

C++ 中的左移 - 意外結果

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM