大端(big endian)和小端(little endian)

来源:互联网 发布:mac 查看命令路径 编辑:程序博客网 时间:2024/05/22 02:30

问题描述:
当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-endian)和小端(little- endian)两个描述。
基本知识:
大端(big endian):低地址存放高有效字节
小端(little endian):低字节存放地有效字节


现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian,ARM则同时支持 big和little,网络编程中,TCP/IP统一采用大端方式传送数据,所以有时我们也会把大端方式称之为网络字节序。

特别需要注意的是,C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而 JAVA编写的程序则唯一采用big endian方式来存储数据。这里我就只讨论C/C++语言的情况。

1.大端和小端的方式及判断
举个例子说明,我的机子是32位windows的系统,处理器是AMD的。对于一个int型数0x12345678,为方便说明,这里采用16进制表示。这个数在不同字节顺序存储的CPU中储存顺序如下:

0x12345678   16进制,两个数就是一字节

高有效字节——>低有效字节: 12 34 56 78

          低地址位     高低址位


大端:  12  34        56   78

小端: 78  56        34   12

2.大端和小端的字节转换

当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序(即大端方式)后再进行传输。此外用C/C++在小端方式的机器上编写的程序与java程序互通时也要进行大端和小端的转换。

这里所谓转换就是改变字节的排序,使交互时数据保持一致。举一个例子,还是16进制表示的数0x12345678,在小端机器上排序为0x78563412,当内存中这样的数传输时,在大端方式下就是0x78563412这个值,与原值不同,要想与原值相同,在传输前,在大端方式下就该是0x12345678,这时原数在内存中为0x12345678,即将原数据0x12345678在内存存储序列为0x12345678,也就是要转换成大端方式。

要传输值:12 34 56 78

不转换时,小端:78 56 34 12

转换为大端:12 34 56 78

3.Java中的情况
虽然Java之中的内存分配都Java本身都已经处理好了,不存在Big Endian和Little Endian的区别。但是,在一些特殊的情况下,我们任然需要知道CPU到底是big endian或者little endian。Java里面可以直接的调用java.nio.ByteOrder类的方法nativeOrder()方法,下面的是测试代码:


在Windows Intel上输出的结果是:LITTLE_ENDIAN

在AIX PPC64上面的输出结果是:BIG_ENDIAN


参考文章:http://blog.chinaunix.net/uid-1844931-id-3022904.html,http://www.cnblogs.com/Romi/archive/2012/01/10/2318551.html;

1 0