大端和小端

理解字节序

大端和小端的问题

对于整型、长整型等数据类型,Big endian 认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而 Little endian 则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放数据的低位字节到高位字节)。

写入

如果我们将0x1234abcd 写入到以 0x0000 开始的内存中,则Little endian 和 Big endian 模式的存放结果如下:

1
2
3
地址           0x0000         0x0001        0x0002          0x0003   
big-endian 0x12 0x34 0xab 0xcd
little-endian 0xcd 0xab 0x34 0x12

读取

假设从内存地址 0x0000 开始有以下数据:

1
2
0x0000         0x0001       0x0002       0x0003  
0x12 0x34 0xab 0xcd

如果我们去读取一个地址为 0x0000 的四个字节变量,若字节序为 big-endian,则读出结果为 0x1234abcd;若字节序为 little-endian,则读出结果为 0xcdab3412。

常见情况

一般来说,x86 系列 CPU 都是 little-endian 的字节序,PowerPC 通常是 big-endian,网络字节顺序也是 big-endian,还有的 CPU 能通过跳线来设置 CPU 工作于 Little endian 还是 Big endian 模式。

x86 gcc

对于 x86 gcc 而言,

1
2
unsigned int i = 0x00646c72;
printf("H%x Wo%s", 57616, &i);

小端模式下:十进制的 57616 是 0xe110,由低地址到高地址的存储是 0x10 0xe1, 0x00646c72 由低地址到高地址的存储是 0x72 0x6c 0x64 0x00;读取的时候,57616 按照小端法正常读取,&i 被分成四部分读取输出,分别是 0x72 0x6c 0x64 0x00,0x00 代表就是空字符,即标识字符串的结束。
大端模式下:十进制的 57616 是 0xe110,由低地址到高地址的存储是 0xe1 0x10, 0x00646c72 由低地址到高地址的存储是 0x00 0x64 0x6c 0x72;读取的时候,57616 按照大端法正常读取,&i 被分成四部分读取输出,分别是 0x00 0x64 0x6c 0x72。因此,大端模式下,想要正常输出的话,需要将 i 修改为 0x726c6400,而 57616 无需做修改。

32 位数大小端互转程序

uint32_t reversebytes_uint32t(uint32_t value){  
    return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 |   
        (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24;   
}  
显示 Gitment 评论