您的位置:首页 > 其它

关于Big Endian 和 Little Endian

2011-05-16 11:01 260 查看
一、字节序



来自:
http://ayazh.gjjblog.com/archives/1058846/
谈到字节序的问题,必然牵涉到两大

CPU
派系。那就是

Motorola


PowerPC
系列

CPU


Intel


x86
系列

CPU


PowerPC
系列采用

big endian
方式存储数据,而

x86
系列则采用

little endian
方式存储数据。那么究竟什么是

big endian
,什么又是

little endian
呢?

其实

big endian
是指低地址存放最高有效字节(

MSB
),而

little endian
则是低地址存放最低有效字节(

LSB
)。

用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678
在两种不同字节序CPU
中的存储顺序如下所示:

Big Endian


低地址
高地址

----------------------------------------->

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| 12 | 34 | 56 | 78 |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian


低地址
高地址

----------------------------------------->

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| 78 | 56 | 34 | 12 |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

从上面两图可以看出,采用big endian
方式存储数据是符合我们人类的思维习惯的。而little endian
,!@#$%^&*
,见鬼去吧
-_-|||

为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?在这里我想说说两种语言。C/C++
语言编写的程序里数据存储顺序是跟编译平台所在的CPU
相关的,而JAVA
编写的程序则唯一采用big endian
方式来存储数据。试想,如果你用C/C++
语言在x86
平台下编写的程序跟别人的JAVA
程序互通时会产生什么结果?就拿上面的0x12345678
来说,你的程序传递给别人的一个数据,将指向0x12345678
的指针传给了JAVA
程序,由于JAVA
采取big endian
方式存储数据,很自然的它会将你的数据翻译为0x78563412
。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C
程序传给JAVA
程序之前有必要进行字节序的转换工作。

无独有偶,所有网络协议也都是采用big endian
的方式来传输数据的。所以有时我们也会把big endian
方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C
中提供了下面四个转换字节序的宏。

big endian

:最高字节在地址最低位,最低字节在地址最高位,依次排列。

little endian
:最低字节在最低位,最高字节在最高位,反序排列。

endian
指的是当物理上的最小单元比逻辑上的最小单元小时,逻辑到物理的单元排布关系。咱们接触到的物理单元最小都是byte
,在通信领域中,这里往往是bit
,不过原理也是类似的。

一个例子:

如果我们将0x1234abcd
写入到以0x0000
开始的内存中,则结果为

big-endian little-endian

0x0000 0x12 0xcd

0x0001 0x34 0xab

0x0002 0xab 0x34

0x0003 0xcd 0x12

目前应该little endian
是主流,因为在数据类型转换的时候(尤其是指针转换)不用考虑地址问题。

二、
Big Endian



Little Endian


名词的由来


这两个术语来自于
Jonathan Swift

的《《格利佛游记》其中交战的两个派别无法就应该从哪一端--小端还是大端--打开一个半熟的鸡蛋达成一致。:)


endian

”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头
(Big-Endian)

敲开还是从小头
(Little-Endian)

敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

我们一般将
endian

翻译成“字节序”,将
big endian


little endian

称作“大尾”和“小尾”。

在那个时代,
Swift

是在讽刺英国和法国之间的持续冲突,
Danny Cohen

,一位网络协议的早期开创者,第一次使用这两个术语来指代字节顺序,后来这个术语被广泛接纳了

三、
Big Endian



Little Endian


优劣


来自:
Dr. William T. Verts, April 19, 1996

Big Endian



判别一个数的正负很容易,只要取
offset0

处的一个字节就能确认。

Little Endian



长度为
1


2


4

字节的数,排列方式都是一样的,数据类型转换非常方便。

四、一些常见文件的字节序



来自:
Dr. William T. Verts, April 19, 1996

Common file formats and their endian order are as follows:

Adobe Photoshop

-- Big Endian

BMP (Windows and OS/2 Bitmaps)

-- Little Endian

DXF (AutoCad)

-- Variable

GIF

-- Little Endian

IMG (GEM Raster)

-- Big Endian

JPEG

-- Big Endian

FLI (Autodesk Animator)

-- Little Endian

MacPaint

-- Big Endian

PCX (PC Paintbrush)

-- Little Endian

PostScript

-- Not Applicable (text!)

POV (Persistence of Vision ray-tracer)

-- Not Applicable (text!)

QTM (Quicktime Movies)

-- Little Endian (on a Mac!)
(PeterLee
注Big Endian in my opinion


Microsoft RIFF (.WAV & .AVI)

-- Both

Microsoft RTF (Rich Text Format)

-- Little Endian

SGI (Silicon Graphics)

-- Big Endian

Sun Raster

-- Big Endian

TGA (Targa)

-- Little Endian

TIFF

-- Both, Endian identifier encoded into file

WPG (WordPerfect Graphics Metafile)

-- Big Endian (on a PC!)

XWD (X Window Dump)

-- Both, Endian identifier encoded into file

五、比特序



来自:
http://ayazh.gjjblog.com/archives/1058846/
我在8
月9
号的《Big Endian
和Little Endian
》一文中谈了字节序的问题。可是有朋友仍然会问,CPU
存储一个字节的数据时其字节内的8
个比特之间的顺序是否也有big endian
和little endian
之分?或者说是否有比特序的不同?

实际上,这个比特序是同样存在的。下面以数字0xB4
(10110100
)用图加以说明。

Big Endian


msb lsb

---------------------------------------------->

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Little Endian


lsb msb

---------------------------------------------->

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

实际上,由于CPU
存储数据操作的最小单位是一个字节,其内部的比特序是什么样对我们的程序来说是一个黑盒子。也就是说,你给我一个指向0xB4
这个数的指针,对于big endian
方式的CPU
来说,它是从左往右依次读取这个数的8
个比特;而对于little endian
方式的CPU
来说,则正好相反,是从右往左依次读取这个数的8
个比特。而我们的程序通过这个指针访问后得到的数就是0xB4
,字节内部的比特序对于程序来说是不可见的,其实这点对于单机上的字节序来说也是一样的。

那可能有人又会问,如果是网络传输呢?会不会出问题?是不是也要通过什么函数转换一下比特序?嗯,这个问题提得很好。假设little endian
方式的CPU
要传给big endian
方式CPU
一个字节的话,其本身在传输之前会在本地就读出这个8
比特的数,然后再按照网络字节序的顺序来传输这8
个比特,这样的话到了接收端不会出现任何问题。而假如要传输一个32
比特的数的话,由于这个数在littel endian
方存储时占了4
个字节,而网络传输是以字节为单位进行的,little endian
方的CPU
读出第一个字节后发送,实际上这个字节是原数的LSB
,到了接收方反倒成了MSB
从而发生混乱。

转自:http://blog.csdn.net/sunshine314/2008/4/20/2309655.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: