掌握知道以下的重点知识就可以了。
1. 字节序
假设
int a = 0x12345678;
16进制数中每位数值占据4 bit;在内存中,是以8个bit作为1byte。
因此0x12345678中每两位作为1byte, 其中0x78是低byte,0x12是高byte。
在内存中的存储方式有两种:
0x12345678的低位(0x78)存在低地址,即方式1,叫做小字节序(Little endian);
0x12345678的高位(0x12)存在低地址,即方式2,叫做大字节序(Big endian);
一般的arm芯片都是小字节序,有些处理器,可以置某个寄存器,让整个系统使用大字节序或小字节序。
2. 位操作
2.1 逻辑移位
在嵌入式开发中,我们只涉及逻辑移位:不关心符号位,都是补0
算术移位,需要分有符号型值和无符号型值:
- 对于无符号型值,算术移位等同于逻辑移位。
- 对于有符号型值 ,算术左移等同于逻辑左移;算术右移补的是符号位,正数补0,负数补1。
2.1.1 逻辑左移
int a = 0x123; int b = a<<2; // b=0x48C
2.1.2 逻辑右移
int a = 0x123; int b = a>>2; // b=0x48
2.2 取反
unsigned int a = 0x123;
unsigned int b = ~a; // b的每一位,都是a对应位的取反
2.3 位与
unsigned int a = 0x123;
unsigned int b = 0x456;
unsigned int c = a & b; // c等于a位与b,即:a,b的每一位进行与操作
两位相与,结果如下:
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
所以,上述C语言代码的结果如下图所示:
2.4 位或
unsigned int a = 0x123;
unsigned int b = 0x456;
unsigned int c = a | b; // c等于a位或b,即:a,b的每一位进行或操作
两位相或,结果如下:
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
所以,上述C语言代码的结果如下图所示:
2.5 置位
unsigned int a = 0x123;
unsigned int b = a | (1<<7) | (1<<8); // 设置a的bit7, bit8, 赋给b
2.6 清位
unsigned int a = 0x123;
unsigned int b = a & ~((1<<7) | (1<<8)); // 清除a的bit7, bit8, 赋给b
2.7 把某几位设置为某值
比如要把bit7设置为1,把bit8清除为0,这可以分两步操作:先设置bit7,再清除bit8。
还有一种情况:bit[8:7]= val, 不知道val的取值是多少,怎么办?
先清除bit8、bit7,再或上val,代码如下:
unsigned int a = 0x123;
unsigned int b = a & ~(3<<7); /* 清除bit7, bit8 */
b = b | (val << 7); /* 设置bit7, bit8为val */