内存中字的存储:字节序之大端和小端

假设有一个16位的CPU,那么它的寄存器大小是16位,即一个寄存器可以存放2字节的数据。当这个CPU寄存器存放一个字长数据时,寄存器的高8位将存放高位字节,寄存器的低8位将存放低位字节。

但是在内存中,因内存被划分成连续编号的存储单元,每个存储单元只能存放1字节数据。所以,存放一个字需要2个存储单元。在存放字时,有两种存放方式:

  • 小端(little endian):字的高位字节–>高位地址单元,字的低位字节–>低位地址单元中(小端高对高)
  • 大端(big endian):字的高位字节–>低位地址单元,字的低位字节–>高位地址单元中

比如,16位寄存器中存放一个16进制为0x0123的2字节int数据,该值在寄存器中的存放方式为:

1
2
3
       高位字节   低位字节
Bin 0000 0001 0010 0011
Hex 01 23

如果要将这2个字节存放到内存,假设从内存单元0开始存放,那么按照这两种存放方式存储时,内存中的存放结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 内存编址方式
低位 高位
---------------------->

######### 小端法 ###########
低位地址 高位地址
Bin 0010 0011 0000 0001
Hex 23 01

######### 大端法 ###########
低位地址 高位地址
Bin 0000 0001 0010 0011
Hex 01 23

人在阅读或书写一个二进制或十六进制数字时,总是高位在左边,低位在右边,这符合寄存器中的高低位顺序,但是内存编址方式(或数组索引)是低位在前,高位在后,两者相反的顺序使得高低位交叉的大端存储法更适合人类阅读,而小端则『反人类』。

采用哪种存储方式并不影响计算机的运行速度,只是影响人的理解,也影响跨主机数据通信。因为不同CPU在将寄存器数据存放到内存(或从内存读取到寄存器)时可能采用不同的方式,所以如果数据跨主机后将可能会出现反序现象。

为了保证跨主机网络通信不会出现数据反序问题,TCP/IP规定了网络字节序为大端方式,即数据在经过网络传输出去时和接收进来时必须采用大端方式。