跳到主要内容

字节顺序(大小端)

字节顺序的定义

我们知道,在计算机系统中,存储数据的基本单位是 字节(Byte),除单字节数据类型(如 C 语言中的 char 型)以外,其他类型的数据都是多字节的。而这些由多字节组成的(Word),其内部字节在内存或数字通信链路中的排列顺序,我们就称为字节顺序,又称端序尾序(Endianness)。

在几乎所有的机器上,多字节对象都被存储为连续的字节序列。因此也就形成了两种通用的字节排列规则,一种称为小端序,另一种称为大端序。也就是常说的“大小端”问题。

  • 小端序(Little-endian):低字节存放在低地址处,高字节存放在高地址处。
  • 大端序(Big-endian):低字节存放在高地址处,高字节存放在低地址处。

例如,一个值为 0x0A0B0C0D 的整型数,采用小端序和大端序时在内存中的存储情况如下图所示。

端(endian)的起源

endian”一词来源于十八世纪爱尔兰作家乔纳森·斯威夫特(Jonathan Swift)的小说《格列佛游记》(Gulliver's Travels)。小说中,小人国为水煮蛋该从大的一端(Big-End)剥开还是小的一端(Little-End)剥开而争论,争论的双方分别被称为“大端派”和“小端派”。

1980年,一位网络协议的早期开发者丹尼·科恩(Danny Cohen)在其著名的论文《On Holy Wars and a Plea for Peace》中,为平息一场关于字节该以什么样的顺序传送的争论,而第一次引用了该词。

字节顺序的应用

字节顺序由 CPU 的体系结构所决定,但对于操作系统之上的应用程序来说,则由操作系统和编译器所决定。只要操作系统和编译器支持,应用程序就可以使用这种字节序。当然,如果操作系统和编译器不支持,我们也可以通过软件的方式进行转换,不过会影响其运行效率。

常见处理器体系所采用的字节顺序如下:

  • x86、MOS Technology 6502、Z80、VAX、PDP-11 等处理器为小端序;
  • Motorola 6800、Motorola 68000、PowerPC 970、System/370、SPARC(除 V9 外)等处理器为大端序;
  • ARM、PowerPC(除 PowerPC 970 外)、DEC Alpha、SPARC V9、MIPS、PA-RISC 及 IA64 的字节序是可配置的。

字节顺序的另外一个重要应用场景是网络传输,包括以太网、I2C、SPI、串口通信等串行通信协议都存在字节顺序的问题。其中,网络传输一般采用大端序,也称为网络字节序

另外,在数字通信链路中还涉及位序的概念,是数据在底层传输时的细节,对于协议开发者和驱动开发者也需要注意该问题。