1. 概念

1.1. 大端模式

  • 高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,即正序排列,高尾端;

CPU的大端模式和小端模式 - 图1

1.2. 小端模式

  • 低位字节排放在内存的低地址端,高位字节排放在内存的高地址端,即逆序排列,低尾端;

CPU的大端模式和小端模式 - 图2

1.3. 具体例子

  • 16bit宽的数 0x1234 在两种模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
    | 内存地址 | 小端模式存放内容 | 大端模式存放内容 | | —- | —- | —- | | 0x4000 | 0x34 | 0x12 | | 0x4001 | 0x12 | 0x34 |

  • 32bit宽的数0x12345678 在两种模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
    | 内存地址 | 小端模式存放内容 | 大端模式存放内容 | | —- | —- | —- | | 0x4000 | 0x78 | 0x12 | | 0x4001 | 0x56 | 0x34 | | 0x4002 | 0x34 | 0x56 | | 0x4003 | 0x12 | 0x78 |

2. 如何判断机器的字节序(*)

  • 一般都是通过 union 来测试 : ```c

    include

int main (void) { union{ short i; char a[2]; }u;//联合体u

u.a[0] = 0x11; u.a[1] = 0x22;

printf (“0x%x\n”, u.i); //0x2211 为小端 0x1122 为大端 return 0; }

  1. - union 型数据所占的空间等于其最大的成员所占的空间。对 union 型的成员的存取都是相对于该联合体基地址的偏移量为 0 处开始,也就是联合体的访问不论对哪个变量的存取都是从 union 的首地址位置开始。
  2. - 联合是一个在同一个存储空间里存储不同类型数据的数据类型。这些存储区的地址都是一样的,联合里不同存储区的内存是重叠的,修改了任何一个其他的会受影响。那么通过强制类型转换,判断其实存储位置,也可以测试大小端了:
  3. ```c
  4. #include <stdio.h>
  5. int main (void) {
  6. short i = 0x1122;
  7. char *a = (char*)(&i);
  8. printf ("0x%x\n", *(a + 0)); //大端为 0x11 小端为 0x22
  9. printf ("0x%x\n", *(a + 1));
  10. return 0;
  11. }

3. 常见的字节序

一般操作系统都是小端,通讯协议是大端的(网络协议常见)

3.1. 常见CPU的字节序

  • Big Endian : PowerPC、IBM、Sun
  • Little Endian : x86、DEC
  • ARM既可以工作在大端模式,也可以工作在小端模式

    3.2. 常见文件的字节序

    | Adobe PS | Big Endian | | —- | —- | | BMP | Little Endian | | DXF(AutoCAD) | Variable | | GIF | Little Endian | | JPEG | Big Endian | | MacPaint | Big Endian | | RTF | Little Endian | | Java和所有的网络通讯协议 | Big-Endian |

4. 学习资料