如果处理器架构支持大端 (big-endian) 字节序,那么最大字节地址对应于数字最低有效字节 (LSB) 上;小端 (little-endian) 字节序则相反:数字最低字节对应于最小字节地址。
《UNIX 环境高级编程》(第二版) P440
字节序
运行在同一台计算机上的进程相互通信时,一般不用考虑字节的顺序(字节序),字节序是一个处理器架构特性,用于指示像整数这样的大数据类型的内部字节顺序。下图显示一个 32 位整数内部的字节是如何排序的。
Intel 平台为小端字节序,如果一个 32 位整数值 0x04030201,数字最高位为 0x04,数字最低位 0x01。以数组形式在内存中存储为:
对应上面所说的:数字最低字节 (0x01) 对应于最小字节地址 n。
查看系统是大端还是小端
在 Linux 系统中提供了 lscpu
命令可用来查看系统的字节序 (Byte Order):
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 42
Stepping: 7
CPU MHz: 1600.000
BogoMIPS: 6585.22
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
NUMA node0 CPU(s): 0-3
在 Linux 内核源码 2.6.14 中:
/* arch/arm/kernel/setup.c */
/* Line: 115-117 */
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.l)
这段代码非常巧妙,利用在 union
中存储的数据从最低位开始存放的特性,如果是小端存放,则输出 l
,如果大端存放,则输出 b
。
注意: 这段代码针对 32 位的 ARM 架构。如果你需要测试这段代码,最快捷的办法注释掉 __initdata
偷懒。
参考资料
[1] Linux 驱动开发研究