小端格式和大端格式(Little-Endian&Big-Endian)

Posted 呆呆象呆呆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小端格式和大端格式(Little-Endian&Big-Endian)相关的知识,希望对你有一定的参考价值。

小端格式和大端格式(Little-Endian&Big-Endian)

1 字节序

字节序,也就是字节的顺序,指的是多字节的数据在内存中的存放顺序。

在几乎所有的机器上,多字节对象都被存储为连续的字节序列。

例如:如果C/C++中的一个int型变量 a 的起始地址是&a = 0x100,那么 a 的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置。

不同的CPU有不同的字节序类型,最常见的有两种:

  • Little-Endian:将低序字节存储在起始地址(低位编址)

  • Big-Endian:将高序字节存储在起始地址(高位编址)

举例说明如下图

然后就牵涉出两大CPU派系:

  • Motorola 6800,PowerPC 970,SPARC(除V9外)等处理器采用Big-Endian方式存储数据;
  • x86系列,VAX,PDP-11等处理器采用Little0Endian方式存储数据。
  • 另外,还有一些处理器像ARM, DEC Alpha的字节序是可配置的。

2 LE(Little-Endian)

最符合人的思维的字节序

地址低位存储值的低位,地址高位存储值的高位。

因为从人的第一观感来说,低位值小,就应该放在内存地址小的地方,也即内存地址低位。反之,高位值就应该放在内存地址大的地方,也即内存地址高位。所以说是最符合人的思维的字节序。

就好比我们从小学的计数法,个位代表的单位值最小,放在最低位,以此类推十位,百位。

优势:长度为1,2,4字节的数,排列方式都是一样的,数据类型转换非常方便。

举个例子:在内存中双字0x01020304(DWORD)和0x1234abcd的存储方式。

内存地址4000400140024003
LE04030201
LE0xcd0xab0x340x12

注:每个地址存1个字节,每个字有4个字节。2位16进制数是1个字节(0xFF=11111111)。

3 BE(Big-Endian)

最直观的字节序

地址低位存储值的高位,地址高位存储值的低位,

只需要把内存地址从左到右按照由低到高的顺序写出,也就是把值按照通常的高位到低位的顺序写出,一个字节一个字节的填充进去即可,直接阅读从低到高的地址里面的数据即可。

举个例子:在内存中双字0x01020304(DWORD)和0x1234abcd的存储方式。

内存地址4000400140024003
BE0x010x020x030x04
BE0x120x230xab0xcd

注:每个地址存1个字节,每个字有4个字节。2位16进制数是1个字节(0xFF=11111111)。

4 为什么要注意字节序

如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。

但是,如果你的程序要跟别人的程序产生交互呢? 比如,当一个 C/C++ 的程序要与一个 Java 程序交互时:

  • C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而现在比较普遍的 x86 处理器是 Little Endian
  • JAVA编写的程序则唯一采用 Big Endian 方式来存储数据

试想,如果你的C/C++程序将变量 a = 0x12345678 的首地址传递给了Java程序,由于Java采取 Big Endian 方式存储数据,很自然的它会将你的数据翻译为 0x78563412。显然,问题就出现了!!!

另外,网络传输一般采用 Big Endian,也被称之为网络字节序,或网络序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。

5 判断机器的字节序

由于 C/C++ 存储数据时的字节序依赖所在平台的CPU,所以我们可以通过C/C++程序判定机器的端序:

void Endianness()

	int a = 0x12345678;
	if( *((char*)&a) == 0x12)
		cout << "Big Endian" << endl;
	else
		cout << "Little Endian" << endl;

参考文献

小端格式和大端格式(Little-Endian&Big-Endian) - 清风行云 - 博客园

字节序:Big Endian 和 Little Endian | 神奕的博客

以上是关于小端格式和大端格式(Little-Endian&Big-Endian)的主要内容,如果未能解决你的问题,请参考以下文章

小端格式和大端格式(Little-Endian&Big-Endian)

大端小端(Big- Endian和Little-Endian)[转]

大端与小端机器

为啥同时使用小端和大端?

网络编程

大端对齐和小端对齐