C语言中对寄存器指定位置0的位操作为何采用~(1 << n)写法?
寄存器位操作置0写法疑问解答
为什么不能用 PORTB &= (0 << 2); 实现指定位置0
我们可以从按位与的运算规则和两种写法的实际效果来分析:
- 按位与(
&)的运算规则:只有两个操作数的对应二进制位都为1时,结果的对应位才为1,否则为0。寄存器位操作的核心要求是仅修改目标位,保留其他位的原有状态,这也是两种写法效果差异的核心原因。 0 << 2的计算结果永远是0,左移操作不会改变0的全0二进制属性。因此PORTB &= (0 << 2);等价于PORTB = PORTB & 0,最终会把寄存器的所有位全部清0,完全不符合只修改指定位的需求。
举个实际例子:假设当前PORTB的值为0b10101010,执行PORTB &= 0后结果为0b00000000,所有位都被清空。- 常规写法
PORTB &= ~(1 << 2);的逻辑:- 先计算
1 << 2,得到只有第2位(从0开始计数)为1、其余位为0的掩码,8位场景下值为0b00000100 - 对上述掩码按位取反,得到只有第2位为0、其余位为1的掩码,8位场景下值为
0b11111011 - 将PORTB和该掩码做按位与,只有第2位会被清0,其余位完全保留原值。
同样用刚才的例子:PORTB原值为0b10101010,执行该语句后结果为0b10100010,仅第2位被清0,其他位状态不变,符合预期。
- 先计算
8位寄存器场景下的字面量0是否对应0b00000000
是的。在8位寄存器的运算场景中,参与位运算的整数字面量会被隐式转换为和寄存器位宽一致的无符号整数,因此字面量0对应的就是8位全0的二进制值0b00000000。
内容的提问来源于stack exchange,提问作者yeuop
相关产品推荐
相关产品推荐

