由于昨天commons io的翻译文章里提到这篇文章,因此做了一下翻译
一篇关于字节序的文章
版权(C) Dr. William T. Verts, 1996年4月19日
根据你所使用的计算机系统(computing system),特别是当你写入一些数字数据到一个文件的时候,你将不得不选择字节序(byte order)即存储多字节(multibyte)数字数据的方案。有两种被成为“小端字节序”(Little Endian)以及“大端字节序”(Big Endian)的字节序。
基础概念(The Basics)
“小端字节序”(Little Endian)表示数字数据的低位(low-order)字节被保存在内存的最低位内存地址(lowest address),而高位(high-order)字节被保存在内存的最高位内存地址(highest address)。(低位字节(little end)优先流入) 例如,一个4字节长整型
字节3 字节2 字节1 字节0
将在内存中被安排如下:
基准地址(Base Address)+0 字节0
基准地址(Base Address)+1 字节1
基准地址(Base Address)+2 字节2
基准地址(Base Address)+3 字节3
英特尔(Intel)处理器(processor)(它们被使用于PC机)使用“小端字节序”(Little Endian)字节序(byte order)。
“大端字节序”(Big Endian)表示数字数据的高位(high-order)字节被存包在内存的最低位的内存地址(lowest address),而低位(low-order)字节被保存在内存的最高位内存地址(highest address)。(高位字节(big end)优先流入) 我们的长整型,可以被存储如下:
基准地址(Base Address)+0 字节3
基准地址(Base Address)+1 字节2
基准地址(Base Address)+2 字节1
基准地址(Base Address)+3 字节0
摩托罗拉(Motorola)处理器(processor)(它们被使用于Mac机)使用“大端字节序”(Big Endian)字节序(byte order)。【译注:由于Apple公司觉得Motorola所开发的CPU升级太慢所以已经更换使用Intel的CPU了,从这里来看是否说明大端字节序已经不常用了呢?】
哪一个更好(Which is Better)?
你可能看到许多关于这两种格式优缺点的讨论,大部分争端都基于PC与Mac的优缺点。两种格式都有他们的优势和劣势。
在“小端字节序”(Little Endian)方式下,汇编语言指令(assembly language instructions)在任何时刻对于加载(pick up)一个1,2,4或更长字节的数字数据时其读取顺序与“小端字节序”(Little Endian)的格式顺序完全一致:优先加载(pick up)最低位字节(the lowest order byte)其偏移为0。因为有内存地址偏移量(address offset)与数字数据字节1:1的关系(偏移量0是字节0),高精度(multiple precision)数学运算程序相对更容易写入。
在“大端字节序”(Big Endian)方式下,由于高位(high-order)字节优先流入,你还可以通过判断偏移量0判断数字数据是正或负。你不需要去知晓数字数据有多长,也不需要去跳过(skip)任何字节来查找包含标记信息的字节。数字数据的存储顺序与它们的显示顺序一样,因此二进制(binary)转换为十进制(decimal)是非常高效的。
对于我们来说这代表什么(What does that Mean for Us)?
尾端顺序(endian order)的存在表示任何时候数字数据被写入到文件时,你不得不去了解文件是被设定(suppose)为是如何编码(construct)。如果你在一个采用大端字节序(Big Endian)记录整型的机器中编写一个图形文件(如一个BMP文件),你必须首先反转(reverse)字节序否则正常的程序来读取你的文件将不正确。
Windows的BMP格式, 自从它被设计为一个小端字节序(Little Endian)结构(architecture),它就一直坚持小端字节序(Little Endian)格式。无论你使用哪个平台(platform)在这种情况下都必须编写你的Save_BMP代码。
常见文件格式以及他们的尾端顺序(endian order)如下所示:
Adobe Photoshop -- “大端字节序”(Big Endian )
BMP (Windows 以及 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 ) (在Mac!)
Microsoft RIFF (.WAV & .AVI) -- 都有
Microsoft RTF (Rich Text 格式(Format)) -- “小端字节序”(Little Endian )
SGI (Silicon Graphics) -- “大端字节序”(Big Endian )
Sun Raster -- “大端字节序”(Big Endian )
TGA (Targa) -- “小端字节序”(Little Endian )
TIFF -- 都有,尾端标记编入文件
WPG (WordPerfect Graphics Metafile) -- “大端字节序”(Big Endian ) (在PC!)
XWD (X Window Dump) -- 都有,尾端标记编入文件
非原生顺序的处理(Correcting for the Non-Native Order)
如果你发现你需要另一种格式(format)的多字节(multibyte)整形,你可以相当简单地去反转(reverse)。用一个函数(function)就可以从一种格式转换(switch)到另一种格式,反方向也可以。一个简单但不高效的方案(version)如下所示:
Function Reverse (N:LongInt) : LongInt ;
Var B0, B1, B2, B3 : Byte ;
Begin
B0 := N Mod 256 ;
N := N Div 256 ;
B1 := N Mod 256 ;
N := N Div 256 ;
B2 := N Mod 256 ;
N := N Div 256 ;
B3 := N Mod 256 ;
Reverse := (((B0 * 256 + B1) * 256 + B2) * 256 + B3) ;
End ;
一个更高效的基于十六进制数字数据的方案(version),使用位操作(bit masking operators)AND,OR,NOT,位移操作(shift operators)SHL以及SHR如下所示:
Function Reverse (N:LongInt) : LongInt ;
Var B0, B1, B2, B3 : Byte ;
Begin
B0 := (N AND $000000FF) SHR 0 ;
B1 := (N AND $0000FF00) SHR 8 ;
B2 := (N AND $00FF0000) SHR 16 ;
B3 := (N AND $FF000000) SHR 24 ;
Reverse := (B0 SHL 24) OR (B1 SHL 16) OR (B2 SHL 8) OR (B3 SHL 0) ;
End ;
当然还有更高效的方法(method),它们有些非常机械以及依赖具体平台(platform)。使用最有效的方法。