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

时间:2015-02-20 09:37:10

标签: c winapi

取自Charles Petzold的书:

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

您几乎可以在每个Windows程序中看到这样的代码。 LOWORD   和HIWORD是Windows头文件中定义的宏   WINDEF.H。如果您有点好奇,这些宏的定义看起来   像这样

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

这两个宏返回WORD值,即16位无符号

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

#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))

这里发生了什么?

4 个答案:

答案 0 :(得分:2)

我想您的观点是,因为WORD保证为16位,所以(WORD)(x >> 16)无论如何都只能是16位,因此掩码是无用的。

或者也许因为DWORD保证是32位无符号,所以(x >> 16)保证不会设置除16以外的任何位。

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

也许这个宏从未更新过。但是我们当然可以说& 0xFFFF不可能导致问题,因此没有理由将其删除。 (不要修复没有破坏的东西!)

保留它可能是个好主意,以防WORD增加。

答案 1 :(得分:1)

在32位寄存器中,hiword位于左侧(16)位, Loword位于右侧(16)位 LOWORD(l)(WORD)(l)& 0XFFFF 这意味着0XFFFF掩码返回值 登记右侧。 HIWORD(1)(WORD)(1)>> 16)& 0XFFFF 这将32位值移动到右侧16位 或者比特。现在我们右边有一个字 0XFFFF面具是anded,这给了我们HIWORD 希望这个答案已经足够了。

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

& 0xFFFF

确保忽略16个第一位

0x12345678 & 0x0000FFFF == 0x00005678

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