大端还是小端?

Posted on 2006-11-07 13:29 nemo 阅读(4847) 评论(4)  编辑  收藏

今天研究SHA-1算法源码,发现注释中一个词怎么也搞不懂:Big-Endian. 在网上查了才知道是大端在前的意思。在http://blog.vckbase.com/smileonce/archive/2005/02/22/3202.aspx 和 http://blog.myrice.com/reddenedmaple/archives/50001922.html中有比较多地介绍。但是很乱,我整理了一下,并加入了自己的一些理解。感谢提供信息的人们。

这两个术语来自于 Jonathan Swift 的《《格利佛游记》其中交战的两个派别无法就应该从哪一端--小端还是大端--打开一个半熟的鸡蛋达成一致。
在那个时代,Swift是在讽刺英国和法国之间的持续冲突,Danny Cohen,一位网络协议的早期开创者,第一次使用这两个术语来指代字节顺序,后来这个术语被广泛接纳了,成为计算机专用名词。除网络传输之外,在计算机硬件中也有使用,通常表示逻辑最小处理单元大于物理最小处理单元时逻辑单元与物理单元的映射方式。
由于这个概念第一次提出时是来指代字节顺序,而且计算机物理最小处理单元通常为一个字节,所以通常情况下无论是大端还是小端都是以字节(8bit)计,在字节之内都是以大端顺序排列。但不排除以后随着计算机的发展将这个数字扩充。

字节排序含义
Big-Endian高位在前,低位在后。
Little-Endian低位在前,高位在后


请看下面这个例子:
如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
                big-endian     little-endian
0x0000     0x12              0xcd
0x0001     0x34              0xab
0x0002     0xab              0x34
0x0003     0xcd              0x12

然后,假如需要从内存中取32位整数0x1234abcd中的高16位整数,就需要知道是不是big-endian,如果是,需要从0x0002地址中去取,如果是little-endian,则需要从0x0000中取。也即怎么存就怎么取。

为什么会出现这样的情况呢?为什么要有这两种方式来排列数据?我们可以看看Dr. William T. Verts所作的说明:

Which is Better?

You may see a lot of discussion about the relative merits of the two formats, 
mostly religious arguments based on the relative merits of the PC versus the Mac. 
Both formats have their advantages and disadvantages.

In "Little Endian" form, assembly language instructions for picking up a 1, 2, 4, or longer byte number proceed 
in exactly the same way for all formats: first pick up the lowest order byte at offset 0. 
Also, because of the 1:1 relationship between address offset and byte number (offset 0 is byte 0), 
multiple precision math routines are correspondingly easy to write.

In "Big Endian" form, by having the high-order byte come first, 
you can always test whether the number is positive or negative by looking at the byte at offset zero. 
You don't have to know how long the number is, nor do you have to skip over any bytes to find the byte containing the sign information. 
The numbers are also stored in the order in which they are printed out, so binary to decimal routines are particularly efficient.

翻译如下:
你可能看见过很多关于这两种形式的相对优点的讨论,最激烈的争论是关于PC和MAC的相对优点。这两种形式都有其优点和缺点。

在“小终结者”形式中,提取一个,两个,四个或者更长字节数据的汇编指令以与其他所有格式相同的方式进行:首先在偏移地址为0的地方提取最低位的字节,因为地址偏移和字节数是一对一的关系,多重精度的数学函数就相对地容易写了。

在“大终结者”的形式中,靠首先提取高位字节,你总是可以由看看在偏移位置为0的字节来确定这个数字是正数还是负数。你不必知道这个数值有多长,或者你也不必跳过一些字节来看这个数值是否含有符号位。这个数值是以它们被打印出来的顺序存放的,所以从二进制到十进制的函数特别有效。

因而,对于不同要求的机器,在设计存取方式时就会不同。
IBM的370主机,多数基于RISC计算机,和Motorola的微处理器使用big-endian方法。TCP/IP也使用big-endian方法(big-endian方法也叫做网络编码)。对于人来说我们的语言都是从左到右的习惯方式。这看上去似乎被认为是自然的存储字符和数字方式-你同样也希望以同样的方式出现在你面前。许多人因此也会认为big-endian是流行的存储方式,正如我们平时所读到的。

然而,Intel处理器(CPUs)和DEC Alphas和至少一些在他们的平台的其他程序都是little-endian的。对于little-endian有一个问题,那就是如果你增加数字的值,你可能在左边增加数字(高位非指数函数需要更多的数字)。因此,经常需要增加两位数字并移动存储器里所有Big-endian顺序的数字,把所有数向右移,这会增加计算机的工作量。不过,使用little-endian的存储器中不重要的字节可以存在它原来的位置,新的数可以存在它的右边的高位地址里。这就意味着计算机中的某些计算可以变得更加简单和快速。

Feedback

# 这个我研究过。  回复  更多评论   

2006-11-08 08:43 by lvcha
java因为存在虚拟机,所以把底层的大端和小端问题屏蔽了,内部都是小端,恰恰与.net相反,它没有屏蔽这件事情。
呵呵,所以他们两个序列化反序列化需要手工处理一下。java端。

# re: 大端还是小端?  回复  更多评论   

2006-11-10 10:36 by nemo
对。Java等的语言编译器必须明确他们开发的目标代码使用的是什么存储方式。如果有必要,可以使用转换器可以用来转换存储顺序。

# re: 大端还是小端?  回复  更多评论   

2009-04-04 21:03 by Moto
反了吧,Big Endian是高位存低址啊。

# re: 大端还是小端?  回复  更多评论   

2009-04-04 21:05 by Moto
哦,没反。有点晕

只有注册用户登录后才能发表评论。


网站导航:
 

posts - 21, comments - 74, trackbacks - 0, articles - 3

Copyright © nemo