我正在查看NIC的数据表规范,它说:
寄存器的位2:3包含网卡速度,4包含链路状态等。如何使用位隔离这些位?
例如,我看到了隔离链接状态的代码,如下所示:
(link_reg & (1 << 4))>>4
但我不太明白为什么是正确的转变。我必须说,我仍然对按位运算不太熟悉,即使我知道如何转换为二进制,以及每个运算做什么,但它听起来并不实用。
发布于 2012-10-17 11:45:05
这取决于你想用那个比特做什么。称为L的链接状态位于某个变量/寄存器中
43210
xxxxLxxxx要隔离您想要的位,并用1对其进行逐位操作:
xxLxxxx
& 0010000
=========
00L00001<<4 =1,带4个零或0b10000,这是您要与之进行and运算的数字。
status&(1<<4) 这将给出0或0b10000的结果。您可以进行布尔比较,以确定它是false (零)还是true (非零)
if(status&(1<<4))
{
//bit was on/one
}
else
{
//bit was off/zero
}如果希望结果为1或0,则需要将结果移动到个数列
(0b00L0000 >> 4) = 0b0000L如果and的结果是零,那么移位仍然是零,如果结果是0b10000,那么4的右移将给出0b00001
所以
(status&(1<<4))>>4 gives either a 1 or 0;
(xxxxLxxxx & (00001<<4))>>4 =
(xxxxLxxxx & (10000))>>4 =
(0000L0000) >> 4 =
0000L另一种使用较少操作的方法是
(status>>4)&1;
xxxxLxxxx >> 4 = xxxxxxL
xxxxxxL & 00001 = 00000L发布于 2012-10-17 11:35:13
最容易看一些二进制数。
下面是一个可能的寄存器值,下面是位索引:
00111010
76543210所以,第4位是1,我们怎么才能得到那个位呢?我们构造一个只包含该位的掩码(我们可以通过将1移到正确的位置,即1<<4),并使用&
00111010
& 00010000
----------
00010000但是我们想要0或1。所以,一种方法是将结果向下移动:00010000 >> 4 == 1。另一种选择是!!val,它将0转换为0,将非零值转换为1(请注意,这只适用于单个位,而不是像链路速度这样的两位值)。
现在,如果您需要位3:2,您可以使用设置了这两个位的掩码。您可以编写3 << 2来获取00001100 (因为3设置了两位)。然后我们用它来&:
00111010
& 00001100
----------
00001000并向下移位2以获得10,即所需的两位。因此,用于获取2位链路速度的语句将为(link_reg & (3<<2))>>2。
发布于 2012-10-17 11:32:45
您可以使用它来确定是否在val中设置了位置pos处的位
#define CHECK_BIT(val, pos) ((val) & (1U<<(pos)))
if (CHECK_BIT(reg, 4)) {
/* bit 4 is set */
}如果两个操作数的相应位都设置为1,则按位and运算符(&)将结果中的每个位设置为1。否则,结果位为0。
https://stackoverflow.com/questions/12926670
复制相似问题