字节序之大小端

在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正确的编/译码从而导致通信失败。

字节序又分为主机字节序和网络字节序

1、主机字节序

目前在各种体系的计算机中通常采用的字节存储机制主要有两种:Big-Endian和Little-Endian,下面先从字节序说起。

字节序,即字节在内存中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。

一般CPU处理数据都以字节为单位,所以这里我们不考虑单个字节的情况,只考虑占内存多于一个字节类型的数据在内存中的存放

顺序。

其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题

大小端:

大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。

小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。

EG:

下面以unsigned int value = 0x12345678这个4个字节32位数据为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value,以从0x4000内存地址开始存放为例

Big-Endian: 低地址存放高位,如下:

高地址
  ---------------
  buf[3] (0x78) -- 低位
  buf[2] (0x56)
  buf[1] (0x34)
  buf[0] (0x12) -- 高位
  ---------------
  低地址

Little-Endian: 低地址存放低位,如下:

高地址
  ---------------
  buf[3] (0x12) -- 高位
  buf[2] (0x34)
  buf[1] (0x56)
  buf[0] (0x78) -- 低位
  --------------

低地址

内存地址 小端模式存放内容 大端模式存放内容
0x4000 0x78 0x12
0x4001 0x56 0x34
0x4002 0x34 0x56
0x4003 0x12 0x78

 

不同的硬件平台,不同的操作系统都有会不同的主机字节序,一般情况下如下图所示:

处理器 操作系统 字节排序
Alpha 全部 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部 Little endian
Motorola680x() 全部 Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非NT Big endian
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM核心 全部 Little endian

2、网络字节序

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian(大端)排序方式。

由于网络字节序的存在、各系统及平台的主机字节序的不同等原因,在网络程序开发或者跨平台开发的应注意保证只使用1种字节序。所以各种编程语言的库函数中会包含以下几种字节序转换函数

htons 把unsigned short类型从主机序转换到网络序

htonl 把unsigned long类型从主机序转换到网络序

ntohs 把unsigned short类型从网络序转换到主机序

ntohl 把unsigned long类型从网络序转换到主机序

在使用little endian的系统中,这些函数会把字节序进行转换,在使用big endian类型的系统中,这些函数会定义成空宏。

猜你喜欢

转载自blog.csdn.net/thebestleo/article/details/82018173