现在的位置: 首页 > 综合 > 正文

从寄存器中指定位置取指定位数值

2013年11月24日 ⁄ 综合 ⁄ 共 2159字 ⁄ 字号 评论关闭

///////////////////////////////////////////////////////////////////////////////
//  GetBitSlice - Get a bit slice from a stream of bytes
//  Input:  pBuffer - buffer containing data stream
//          cbBuffer - size of buffer in bytes
//          dwBitOffset - bit offset from start of buffer
//          ucBitCount - number of bits (less than or equal to 32)
//  Output:
//
//  Return: returns a DWORD contain the bit slice shifted to fill the least significant bits
//  Notes:  will raise an SEH exception if integer overflow occurs
///////////////////////////////////////////////////////////////////////////////

DWORD GetBitSlice(PUCHAR pBuffer, ULONG cbBuffer, DWORD dwBitOffset, UCHAR ucBitCount)
{
    UCHAR rgbShifted[4] = { 0 };
 DWORD dwUsedBytes; // How many bytes have valid data.
 DWORD dwLastByteIndex;
 DWORD dwRemainderShift;
 DWORD dwRet;

    if (ucBitCount > 32) {
        DEBUG_CHECK(FALSE, (TEXT("GetBitSlice: invalid number of bits /n")));
        return 0;
    }

    // Shift the pBuffer down by dwBitOffset bits.
    ShiftBytes(pBuffer, cbBuffer, dwBitOffset, rgbShifted);

    if (ucBitCount % 8 == 0) {
        // Return a byte multiple.
        dwUsedBytes = ucBitCount / 8;
    }
    else {
        // Clear the last used byte of upper bits.
        dwLastByteIndex = (ucBitCount - 1) / 8;
        dwRemainderShift = 8 - (ucBitCount % 8);
        rgbShifted[dwLastByteIndex] <<= dwRemainderShift;
        rgbShifted[dwLastByteIndex] >>= dwRemainderShift;
        dwUsedBytes = dwLastByteIndex + 1;
    }

    // Clear the unused bytes.
    if (dwUsedBytes != sizeof(rgbShifted)) {
        memset(rgbShifted + dwUsedBytes, 0, sizeof(rgbShifted) - dwUsedBytes);
    }

    memcpy(&dwRet, rgbShifted, sizeof(dwRet));

    return dwRet;
}

 

static
VOID ShiftBytes(PBYTE pbInput, ULONG cbInput, DWORD dwBitOffset, PBYTE pbOutput)
{
 DWORD dwRemainderShift;
    DWORD dwByteIndex;
 DWORD dwEndIndex;
 DWORD dwCurrOutputIndex = 0;
 
 dwByteIndex = dwBitOffset / 8;
    dwBitOffset %= 8;

    dwRemainderShift = 8 - dwBitOffset;

    // Only copy 4 bytes max.
    dwEndIndex = min(dwByteIndex + sizeof(DWORD), cbInput);
   
    while (dwByteIndex < dwEndIndex) {
        pbOutput[dwCurrOutputIndex] = pbInput[dwByteIndex] >> dwBitOffset;

        ++dwByteIndex;

        if (dwByteIndex != cbInput) {
            BYTE bTemp = pbInput[dwByteIndex];
            bTemp <<= dwRemainderShift;
            pbOutput[dwCurrOutputIndex] |= bTemp;
        }

        ++dwCurrOutputIndex;
    }
}

抱歉!评论已关闭.