学习完位运算已经有一段时间了,今天回过头来看看,顺便做些总结;位运算在驱动开发中是经常遇到的,尤其是置0和置1。既要指定的位数发生变化,又不能改变其它位的值。还要高效率的编写代码。这时候技巧就很重要了。在位运算中有几个符号: | 按位或 , & 按位与,^ 异或 , ~按位非
(1)如果要把x的某位变为0,就把x 与(&)上 1 上移(<<)n位的非(~)
eg:i = 14 // 1110 (把第2位变为0)
i = i & ~(1 << 2)
(2)如果要把x的某位变为1,就把x 或(|)上 1上移 n 位
eg:i = 7 // 111 (把第2位变为1)
i = i | ( 1 << 2)
但是一般寄存器都是用16进制来表示,假如要让寄存器的N位为1 只要将 1<<N位 再 | 这个数即可。
假如要让寄存器的N位为0 只要将 1<<N位 ,,,取反 再 & 上这个数
1 #include <stdio.h> 2 3 int main() 4 { 5 unsigned int i = 0xa3bf4e72;//0x1010 0011 1011 1111 0100 1110 0111 0010 6 unsigned int ret = 0; 7 8 //将i的第3位变为1 9 ret = i | (1 << 3); 10 printf("i is: 0x%x\n", i); 11 printf("ret is: 0x%x\n", ret);//0x1010 0011 1011 1111 0100 1110 0111 1010(0xa3bf4e7a) 12 //将i的第4为变为0 13 ret = i & ~(1 << 4); 14 printf("i is: 0x%x\n", i); 15 printf("ret is: 0x%x\n", ret);//0xa3bf4e62 16 //将i的4-7变为1 17 ret = i | (0xf << 4); 18 printf("i is: 0x%x\n", i); 19 printf("ret is: 0x%x\n", ret);//0xa3bf4ef2 20 //将i的8-13变为0 21 ret = i & ~(0x3f << 8); 22 printf("i is: 0x%x\n", i); 23 printf("ret is: 0x%x\n", ret);//0xa3bf4072 24 //将i的12-16变为0,18-26变为1 25 ret = i & ~(0x1f << 12) | (0x1ff << 18); 26 printf("i is: 0x%x\n", i); 27 printf("ret is: 0x%x\n", ret);//oxa7fe0e72 28 //将i的12-16变为1,18-26变为0 29 ret = i & ~(0x1ff << 18) | (0x1f << 12); 30 printf("i is: 0x%x\n", i); 31 printf("ret is: 0x%x\n", ret);//oxa003fe72 32 33 return 0; 34 }