我不明白为什么 HIWORD 宏使用 &0xFFFF 掩码?

I can't understand why HIWORD macro uses &0xFFFF mask?

摘自 Charles Petzold 的书:

case WM_SIZE:
 cxClient = LOWORD (lParam) ;
 cyClient = HIWORD (lParam) ;
 return 0 ;

You'll see code like this in virtually every Windows program. LOWORD and HIWORD are macros that are defined in the Windows header file WINDEF.H. If you're curious, the definitions of these macros look like this

#define LOWORD(l) ((WORD)(l))
#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF)) 

The two macros return WORD values that is, 16−bit unsigned

我只会在 HIWORD 定义中使用移位运算符。 像这样:

#define HIWORD(l) ((WORD)(((DWORD)(l) >> 16))

他为什么要掩盖这个价值?

有人可以按位向我解释一下吗?

编辑:

HIWORD(l) ((WORD)(((DWORD)(l) >> 16) & 0xFFFF))


l=0x11223344
((DWORD)(l) >> 16) l becomes 0x00001122
(((DWORD)(l) >> 16) & 0xFFFF))

我这里发生了什么事?

& 0xFFFF

确保忽略前 16 位

0x12345678 & 0x0000FFFF == 0x00005678

移位并不能确保你会留下零(尝试移位 -1),因此他们使用按位并确保这一点。

我猜你的意思是,因为WORD保证是16位,那么(WORD)(x >> 16)无论如何也只能是16位,所以mask没用。

或者因为 DWORD 保证是 32 位无符号的,所以 (x >> 16) 保证除了低 16 位之外没有任何位设置。

在早期,WORD 旨在匹配系统的 CPU 字长(即 int)。然而,事实证明,编写了太多不可移植的代码,以至于当 Win32 出现时,它会破坏太多东西,无法使 WORD 32 位和 DWORD 64 位。

也许这个宏从未更新过。但是我们可以肯定地说 & 0xFFFF 不可能引起问题,所以没有理由删除它。 (不要修理没坏的东西!)

也许保留它甚至是个好主意,以防万一 WORD 增加。

我的猜测是一些旧的编译器会抱怨(在编译过程中产生警告)如果不使用 & 0xFFFF 可能会被截断,即使正如该线程中其他地方指出的那样不需要它。

在32位寄存器中hiword在左边(16)bits, Loword在右侧(16)位 LOWORD(l) (WORD)(l)&0XFFFF 表示0XFFFF掩码returns的值 寄存器的右侧。 HIWORD(l) (WORD)(l)>>16)&0XFFFF 这会将 32 位值向右移动 16 位 或者 bits.so 我们右边有一个词,现在 0XFFFF 掩码是加号,这给了我们 HIWORD 希望这个答案足够了。