Endianness
字节序大家见得比较多,网络上论述也比较多。这里简要介绍:
书写十六进制数据时,我们习惯上MSB在左,而LSB在右。
- LSB: least significant byte
- MSB: most significant byte
-
大端:Big-endian
数据在内存中(地址由低到高)的存放顺序和书写顺序是一致的。
记忆方法:低地址放的是数据的MSB,所以称作大端。 -
小端:Litthle-endian
数据在内存中(地址由低到高)的存放顺序和书写顺序是相反的。
记忆方法:低地址放的是数据的LSB,所以称作小端。即“高高低低”。
高地址存MSB,低地址存LSB。
Bit numbering
我们知道一个字节有8位,也就是8个比特位。从第0位到第7位共8位。
位序描述比特位在字节中的存放顺序。
可参阅维基百科中关于位序的描述。
这里的LSB及MSB的用词代表的是:
- LSB是指 least significant bit
- MSB是指 most significant bit
位序分为两种:
- LSB 0
字节的第0位存放数据的least significant bit,即我们的数据的最低位存放在字节的第0位。
以十进制150为例,0b10010110
在LSB 0方式下存放形式为:
| 7 0 |
---------------------------------
| 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 |
---------------------------------
Least Significant Bit First means that the least significant bit will arrive first.
数据流从bit0开始传送,故数据流出现的顺序是01101001
- MSB 0
字节的第0位存放数据的most significant bit,即我们的数据的最高位存放在字节的第0位。
以十进制150为例,0b10010110
在MSB 0方式下存放形式为:
| 7 0 |
---------------------------------
| 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 |
---------------------------------
Most Significant Bit First means that the most significant bit will arrive first.
也就是说数据流出现的顺序是10010110
实际机器类型
字节序是小端的CPU通常其位序位LSB 0。所以很容易理解,数据不仅在内存中是“高高低低”存放,其位序也是“高高低低”放置的,即msb放在bit7位置上,lsb放置在bit0位置上。
值得注意的是,字节序是大端的CPU采用的位序却不是那么统一,既有MSB 0,也要LSB 0的机器。
字节序测试
#include <stdio.h>
int main()
{
union{
char c;
int i;
}u;
u.i = 0x0201;
if(u.c == 1)
printf("little-endian\n");
else if(u.c == 2)
printf("big-endian\n");
else
printf("unknown\n");
return 0;
}
位序测试
union {
struct {
unsigned char a1:2;
unsigned char a2:3;
unsigned char a3:3;
} x;
unsigned char b;
} d;
int main (void)
{
d.b = 150; //100 == 1001 0110
printf("0x%x\n0x%x\n0x%x\n", d.x.a1, d.x.a2, d.x.a3);
return 0;
}
/* bit numbering: lsb 0
* 0x2 (== 10)
* 0x5 (== 101)
* 0x4 (== 100)
* */
/* bit numbering: msb 0
* 0x1 (== 01)
* 0x2 (== 010)
* 0x3 (== 011)
* */