gpt4 book ai didi

c++ - 从 DWORD 中提取 lo 和 hi 字时为什么需要二进制移位?

转载 作者:行者123 更新时间:2023-11-30 19:26:12 26 4
gpt4 key购买 nike

首先对标题感到抱歉,我不想让它太长或令人困惑。如果有人可以帮助我使它更通用,因为这种情况可能适用于任何类型的位掩码操作。

[以下代码在 Windows 中运行(因此是小端)]

如果我有一个 DWORD(无符号长整型)和一个 WORD(无符号短整型),并且我想从双字中提取低位和高位字,为什么我不能这样做?

DWORD t = 0xAAAABBBB;
WORD loWord = t & 0x0000FFFF;
WORD hiWord = t & 0xFFFF0000;

对于 loWord,我得到正确的答案 0xBBBB,对于 hiWord,我只得到 0(请参阅最后的程序完整列表,以获取结果的打印输出)

我查了一下 Windows 宏是如何执行 HIWORD(_dw) 的,它所做的只是向右移动两个字节,然后像这样执行 AND 操作

DWORD t= 0xAAAABBBB;
WORD hiWord = (t >> 16) & 0xFFFF;

但是我不明白的是,如果我们向右移动两个字节,为什么我们现在还需要执行 AND 运算?为什么甚至需要这种转变,为什么我的原始代码不能按预期工作?

为了说明为什么我对 AND 后的转变感到困惑,这就是我想象的转变工作方式:

0x AA AA BB BB  >> 16  -> 0x 00 00 AA AA 

这样做0x 00 00 AA AA & 0x00 00 FF FF在我看来毫无意义?我缺少什么?

更准确地说,宏首先将 DWORD 转换为指针,然后进行移位,如下所示(这是确切的宏)

#define HIWORD(_dw)     ((WORD)((((DWORD_PTR)(_dw)) >> 16) & 0xffff))

有人可以向我解释一下指针转换的目的吗?我尝试过使用和不使用,结果是一样的。

这是我在测试过程中使用的一个实际的短程序,用于完整说明该问题:

#include <iostream>
#include <Windows.h>


int main()
{
DWORD t = 0xAAAABBBB;
WORD loWord = t & 0x0000FFFF;
WORD hiWordNoShift = t & 0xFFFF0000;
WORD hiWordShift = (t >> 16) & 0xFFFF;

cout << "t: " << std::hex << t << endl;
cout << "hi (no shift): " << std::hex << hiWordNoShift << endl;
cout << "hi (shift): " << std::hex << hiWordShift << endl;
cout << "lo: " << std::hex << loWord << endl;



system("pause");
return 0;
}

结果是:

t: aaaabbbb
hi (no shift): 0
hi (shift): aaaa
lo: bbbb
Press any key to continue . . .

最佳答案

我认为是这样,因为HIWORD()应该是通用的并且应该采用CPU寄存器的大小。

在 64 位目标上,通用寄存器(如 RAX)是 64 位寄存器,并且 DWORD_PTR 的大小也是 64 位。在 32 位目标上,通用寄存器(如 EAX)是 32 位寄存器,并且 DWORD_PTR 的大小也是 32 位。

这样编译器就可以生成更优化的代码。

关于c++ - 从 DWORD 中提取 lo 和 hi 字时为什么需要二进制移位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57835235/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com