descriptor = limit & 0x000F0000;
descriptor |= (flag << 8) & 0x00F0FF00;
descriptor |= (base >> 16) & 0x000000FF;
descriptor |= base & 0xFF000000;
我理解和操作用于屏蔽某些位的事实。但是这里使用的OR操作是什么?请详细说明 这是创建全局描述符表的代码的一部分。
答案 0 :(得分:3)
如果只查看一个位,真值表由
给出0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
因此,当且仅当在至少一个操作数中设置该位时,按位或设置一个位。
当您使用按位或对多于一位的变量使用时,上述真值表将以按位方式应用。
因此,假设您有两个二进制表示为
的变量001101
011001
当您按位或组合它们时,您将收集在 变量中设置的所有位。结果是
011101
bitwise或运算符通常用于向一组位标志添加新标志。该值用于表示数学集。为每个位分配特定含义,该特定含义与通用集的成员相关联。当该位为1时,该成员包含在该集合中,当该位为0时,该关联成员不在该集合中。
所以,让我们有一个非常简单的例子,其中包含两个成员的通用集。让我们调用变量controlState
。位0表示可见属性,位1表示启用的属性。所以,你可以像这样定义标志
const int visibleFlag = 1; // 01 in binary
const int enabledFlag = 2; // 10 in binary
然后你可以像这样构建controlState
变量:
int controlState = 0; // empty set
if (isVisible)
controlState |= visibleFlag;
if (isEnabled)
controlState |= enabledFlag;
如果您不知道是否设置了特定位,它会变得更有趣。因此,您可以确保可见位设置如下:
controlState = ...; // could set visible flag, or not ...
controlState |= visibleFlag;
controlState
的原始值是否包含该标志并不重要。在此操作之后,它将被设置为肯定,并且没有其他标志被更改。
这是您的代码示例中发生的事情。所以,
descriptor = limit & 0x000F0000;
初始化descriptor
。然后
descriptor |= (flag << 8) & 0x00F0FF00;
添加(flag << 8) & 0x00F0FF00
。等等。
答案 1 :(得分:2)
你所展示的代码是通过从其他布尔表达式中选择它的不同部分来构造descriptor
。
请注意(flag << 8)
,(base >> 16)
和base
与ORed一起进行AND运算的常量会产生0xFFFFFFFF
。
OR的要点是,“前8位来自(base >> 16)
,后8位来自flag << 8
,后4位来自limit
,后4位来自flag << 8
base
以及d[7], d[6], b[5], a[4], b[3], b[2], c[1], c[0]
中的最后8位。“最后,描述符看起来像这样:
a
每个逗号分隔变量都是十六进制数字,而b
,c
,d
和limit
是
分别为(flag << 8)
,(base >> 16)
,base
和{{1}}。 (逗号只是为了便于阅读,它们代表数字的连接)。
答案 2 :(得分:1)
在这里使用|=
基本上是以下
descriptor = destriptor | ((flag << 8) & 0x00F0FF00);
答案 3 :(得分:0)
按位OR |
运算符(如果它存在于任一操作数中,则复制一位)用于将descriptor
与=
的右手运算符进行“或”并将结果存储到{ {1}}。它相当于
descriptor
OR操作的真值表:
对于descriptor = descriptor | (flag << 8) & 0x00F0FF00;
和x = 1 1 0 0
OR操作如下:
答案 4 :(得分:0)
descriptor
是一组包含在一起作为位域的值。此代码是根据四个值(limit
,flag
和base
的两个部分)构建的。每个步骤都将值移动到校正位位置,然后使用掩码进行“与”运算,以确保位不会溢出到其他位置。 A |= B
运算符会扩展为A = A | B
并将所有单个结果合并在一起。这也可以使用带有位域的struct
来完成,尽管可能具有较低的可移植性。