大小端

← 返回 Cortex-M4内核原理 | ← 主页

大端序 vs 小端序

大小端描述的是:一个多字节数(如 32 位 int)在内存里哪个字节放最低地址

大端序 Big-Endian小端序 Little-Endian
规则高字节存低地址低字节存低地址
直觉「大」的在前面,符合人读数字习惯「小」的在前面

uint32_t num = 0x12345678 存到地址 0x00 为例(从低地址到高地址):

小端: 0x78  0x56  0x34  0x12
大端: 0x12  0x34  0x56  0x78

谁用哪种

端序谁在用
大端网络协议(IP 地址、端口 = 网络字节序)、JPEG/PNG 等文件格式、部分通信协议
小端ARM(Cortex-M 默认小端)、x86/x64

所以写网络程序、解析协议包时,常要 htonl/ntohl(主机序 ↔ 网络序)转换。 ARM 理论上可配置大小端(Cortex-M 的 AIRCR 位),但实际几乎全用小端。


判断方法

两种写法同一原理:写一个已知值 0x12345678,读最低地址的那个字节,看是低字节 0x78(小端)还是高字节 0x12(大端)。

① 指针强转

uint32_t num = 0x12345678;
uint8_t *p = (uint8_t *)#   // 强转成字节指针,逐个看字节
 
if (p[0] == 0x78) {
    // 最低地址存的是最低字节 → 小端
} else {                         // p[0] == 0x12
    // 大端
}

② 联合体

union {
    uint32_t num;
    uint8_t  bytes[4];
} u;
 
u.num = 0x12345678;
 
if (u.bytes[0] == 0x78) {
    // 小端
} else {                          // u.bytes[0] == 0x12
    // 大端
}

联合体里 numbytes[] 共享同一块内存,所以 bytes[0] 就是 num 的最低地址字节,等价于指针强转。