Little endian 和 Big endian 是 CPU 存放数据的两种不同方式。
对于整型、长整型等数据类型:
- Big endian :认为第一个字节是
最高位字节
(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);
- Little endian :认为第一个字节是
最低位字节
(按照从低地址到高地址的顺序存放数据的低位字节到高位字节)。
例如,假设从内存地址0x0000 开始有以下数据:0x12, 0x34, 0xab, 0xcd
Endian |
0x0000 |
0x0001 |
0x0002 |
0x0003 |
big-endian |
0x12 |
0x34 |
0xab |
0xcd |
little-endian |
0xcd |
0xab |
0x34 |
0x12 |
问题:如何判断系统中的 CPU 是 Little endian 还是 Big endian 模式?(假设机器为:32 位)
解答:将一个字节的数据和一个整型数据存放于同样的内存始地址,通过读取整型数据,分析数据在整型数据的高位还是低位来判断 CPU 是 Little endian 还是 Big endian 模式。
例码1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| typedef enum __endianType { Endian_little, Endian_big, }EndianType;
EndianType CheckEndian1() { typedef unsigned char BYTE; unsigned int num, *p_num; p_num = # num = 0; *(BYTE *)p_num = 0xff; if(0xff == num) { return Endian_little; } else { return Endian_big; } }
|
例码2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| typedef enum __endianType { Endian_little, Endian_big, }EndianType;
EndianType CheckEndian2() { union { unsigned int a; char c; }endianUnion; endianUnion.a = 1; if (1 == endianUnion.c) { return Endian_little; } else { return Endian_big; } }
|
例码3:(Linux 内核的实现方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| typedef enum __endianType { Endian_little, Endian_big, }EndianType;
EndianType CheckEndian3() { union { char c[4]; unsigned int num; } endianUnion = {'l', '?', '?', 'b'}; if ('l' == (char)endianUnion.num) { return Endian_little; } else { return Endian_big; } }
|