乾坤一笑 阅读(1050) 评论(35)

再网上查阅了很多资料(包括中英版的MSDN),反复体会,才基本弄明白一些Big-Endian和Little-Endian的含义,先总结如下:

Big-Endian 和 Little-Endian 字节排序

字节排序 含义
Big-Endian 一个Word中的高位的Byte放在内存中这个Word区域的低地址处。
Little-Endian 一个Word中的低位的Byte放在内存中这个Word区域的低地址处。

必须注意的是:表中一个Word的长度是16位,一个Byte的长度是8位。如果一个数超过一个Word的长度,必须先按Word分成若干部分,然后每一部分(即每个Word内部)按Big-Endian或者Little-Endian的不同操作来处理字节。

一个例子:
如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
                big-endian     little-endian
0x0000     0x12              0xcd
0x0001     0x34              0xab
0x0002     0xab              0x34
0x0003     0xcd              0x12
(注意:0xab换算成2进制是10101011,是个8位的数。我刚才居然当成4位了,自己把自己搞晕了,shit。)

-----------
疑问:为什么要以一个Word为基础单位来分割而不是一个DoubleWord或者Byte?究竟就是这么定义的还是跟具体的CPU有关,跟具体的模式(比如说16位模式、32位模式、64位模式的LE和BE定义会不同)有关?我实在是不清楚,望知道的大侠不吝指点,也希望有这方面资料(文章、代码)的朋友贴一些上来。

评论列表
freedk
re: Big-Endian 和 Little-Endian 两者概念的区别
  big-endian     little-endian
0x0000     0x12              0xcd
0x0001     0x23这里是23,难道不是34??            0xab
0x0002     0xab              0x34
0x0003     0xcd              0x12
穿越无边
re: Big-Endian 和 Little-Endian 两者概念的区别
估计是笔误
gyshen
楼上不要吹毛求疵啊,:)
楼上不要吹毛求疵啊,:)
gyshen
re: Big-Endian 和 Little-Endian 两者概念的区别
如果一个数超过一个Word的长度,必须先按Word分成若干部分,然后每一部分(即每个Word内部)按Big-Endian或者Little-Endian的不同操作来处理字节。
这句话的意思,不明白。

big endian的意思就是最高位在低内存位置,最低位在高内存位置。
周星星
re: Big-Endian 和 Little-Endian 两者概念的区别
顶gyshen所说的,big endian的意思就是高位在前,低位在后,little endian则相反,哪有什么“必须先按Word分成若干部分”的说法,int16如是,int32、int64也如是,float如是,double也如是。
乾坤一笑
to gyshen & 周星星:
不知道我下面这段说的准确不:
WORD的意思是字长,(撇开WINDOWS先不谈,) 一个机器的字是访问内存的单位,就是说系统是以字来访问内存的。不同机器的字长可能不同,比如字长为4字节的话,那么所有的word从word address的0开始线性增加,Byte 1 - 4 放在地址0里面表示第一个word, byte 5 - 8 放在地址1里面表示第二个word,以此类推。那么可能有下面的图:
Big-Endian Format:

bit--> 31~24 23~16 15~8 7~0
high address word address
^ 5 6 7 8 0001
| 1 2 3 4 0000
low address
(图正中间的 1~8 表示第几个被读出字节)

Little-Endian Format:

bit--> 31~24 23~16 15~8 7~0
high address word address
^ 8 7 6 5 0001 ^
| 4 3 2 1 0000 |
low address
(图正中间中的 1~8 表示第几个被读出字节)




乾坤一笑
to freedk :
改过了
rovershen
re: Big-Endian 和 Little-Endian 两者概念的区别
跟word或者说字长根本就没关系,只是字节的排列顺序而已。
big endian:最高字节在地址最低位,最低字节在地址最高位,依次排列。
little endian:最低字节在最低位,最高字节在最高位,反序排列。

目前应该little endian是主流,因为在数据类型转换的时候(尤其是指针转换)不用考虑地址问题
freedk
re: Big-Endian 和 Little-Endian 两者概念的区别
to:rovershen "目前应该little endian是主流,因为在数据类型转换的时候(尤其是指针转换)不用考虑地址问题" 举个例来看看
乾坤一笑
to rovershen :
如果说"跟word或者说字长根本就没关系",假设有一数据文件里面有N多数顺序排布,如果想以Little-Endian format读入内存某区域,那么应该怎么读?怎么排?
问题男
re: Big-Endian 和 Little-Endian 两者概念的区别
目前的存储器,多以byte为访问的最小单元,于是endian的问题应运而生了,当一个逻辑上的整理必须分割为物理上的若干单元时就存在了先放谁后放谁的问题

存在“如果说"跟word或者说字长根本就没关系",假设有一数据文件里面有N多数顺序排布,如果想以Little-Endian format读入内存某区域,那么应该怎么读?怎么排?”这样的问题是由于对于endian的实质理解的偏差,endian指的是当物理上的最小单元比逻辑上的最小单元小时,逻辑到物理的单元排布关系。这里的“有一数据文件里面有N多数顺序排布”,这个“有一数据”显然不是逻辑上的最小单元,而其中的“N多数”的一个才是逻辑最小单元,于是可应用楼主表格中的原则排列,而“N多数”之间的顺序则是由这“N多数”的宿主决定的,比如是你写的程序,这个顺序由你决定

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

实践可以给你更多的经验,比如在一个嵌入式系统的通信协议中,从底层射频驱动到上层的协议栈全部需要实现,那么很可能遇到多个endian的问题,底层的bit序、协议层的byte序、应用层的byte序,这些都是不同的概念

絮絮叨叨,一些拙见
乾坤一笑
to 问题男:
嗯,你的解释让我头脑清晰了很多,谢谢!:)
rovershen
to freedk
没记错的话,除了moto的68K系列和dec的sparc是big endian外,常见的cpu都是little endian。ARM同时支持big和little,实际应用中通常使用little endian。我所说的指针转换,实际上指编译器的隐式处理。
假设有个32位的整数,地址是0x10000000,现在要将它作为16位整数处理,忽略高位,如果是little endian,则直接从0x10000000取得,而如果是big endian,则要从0x10000002取得。
rovershen
to 一笑
关于n多数据的处理,跟endian模式又没有关系了,只要是同种endian模式,怎么存就怎么取。。。
乾坤一笑
to rovershen :
嗯,这玩艺确实很抽象,回来编写代码实践实践就好了。
穿越无边
re: Big-Endian 和 Little-Endian 两者概念的区别
这两个术语来自于 Jonathan Swift 的《《格利佛游记》其中交战的两个派别无法就应该从哪一端--小端还是大端--打开一个半熟的鸡蛋达成一致。:)
在那个时代,Swift是在讽刺英国和法国之间的持续冲突,Danny Cohen,一位网络协议的早期开创者,第一次使用这两个术语来指代字节顺序,后来这个术语被广泛接纳了
摘自《深入理解计算机系统》
很好的一本书:)
阿荣
re: Big-Endian 和 Little-Endian 两者概念的区别
字节序一般是硬件的特点,除了常见的你说的这两种,还有其他很多种,你可以看看XML技术内幕这本书,介绍了很多
绅士亦花心
re: Big-Endian 和 Little-Endian 两者概念的区别
回问题男:
是呀,现在我们并没有考虑位的顺序,因为我们处理的最小单元是字节,我们都假定它是低位在右,高位在左,在一些硬件设备中,位的顺序也会有所变化,那么当我们访问位时,就要注意位的顺序,不知道这个叫什么名词。

回阿荣:
不知还有其他哪些?
jianzh27
re: Big-Endian 和 Little-Endian 两者概念的区别
硬件中也有Big-Endian 和 Little-Endian 的概念,我也是刚刚接触,看了这个帖子,我想大概是怎么回事了。

我的理解是这样:以”字节“为单位,用Big-Endian 或 Little-Endian 模式来统一读写数据的方式,但是”字节“的每一位对硬件来说也还有另外一种选择模式,看顺的还是逆的。在实际应用的时候,”字节“也可能是”字“,也可能是”双字“,主要是为了处理方便,要看处理器的位数了。

其实大家也都了解的差不多了,只是还没有定论。

谢谢各位,我从中间也学到一点东西。
恒(翻译)
re: Big-Endian 和 Little-Endian 两者概念的区别
你可能看见过很多关于这两种形式的相对优点的讨论,最激烈的争论是关于PC和MAC的相对优点。这两种形式都有其优点和缺点。

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

在“大终结着”的形式中,靠首先提取高位字节,你总是可以由看看在偏移位置为0的字节来确定这个数字是正数还是负数。你不必知道这个数值有多长,或者你也不必跳过一些字节来看这个数值是否含有符号位。这个数值是以它们被打印出来的顺序存放的,所以从二进制到十进制的函数特别有效。
xhmars
re: Big-Endian 和 Little-Endian 两者概念的区别
我觉得“大端在前”和“小端在前”只在不同CPU体系之间数据传递时才必须分清。比如用串口或网口,无论什么类型的,都是一个子Byte一个Byte顺序传递的,如果不事先调整的话传递过去后就乱套了。
hawk
re: Big-Endian 和 Little-Endian 两者概念的区别
如果是16位机,0x1234abcd如何写呢?
是如下方式吗?
       big 12
          34
          ab
          cd
   little 34
          12
          cd
          ab
吗?
hawk
re: Big-Endian 和 Little-Endian 两者概念的区别
如果是16位机,0x1234abcd如何写呢?
是如下方式吗?
       big 12
          34
          ab
          cd
   little 34
          12
          cd
          ab
吗?
hawk
re: Big-Endian 和 Little-Endian 两者概念的区别
如果是16位机,0x1234abcd如何写呢?
是如下方式吗?
       big 12
          34
          ab
          cd
   little 34
          12
          cd
          ab
吗?
快乐宇宙
re: Big-Endian 和 Little-Endian 两者概念的区别
是不是应该这样:
            big  12
               34
               ab
               cd
       little  cd
               ab
               34
               12
nrzi
re: Big-Endian 和 Little-Endian 两者概念的区别
应该这么写吧?
            big-endian     little-endian
0x0000     0x3412              0x1234
0x0001     0xcdab              0xabcd
Angnes
re: Big-Endian 和 Little-Endian 两者概念的区别
IP协议传输用big endian,所有little endian 要转成big endian.上面规定的是用8bit分割,也就是字节分割。所以分割应该是根据具体情况不同吧~
shanzy
re: Big-Endian 和 Little-Endian 两者概念的区别
疑问:为什么要以一个Word为基础单位来分割而不是一个DoubleWord或者Byte?究竟就是这么定义的还是跟具体的CPU有关,跟具体的模式(比如说16位模式、32位模式、64位模式的LE和BE定义会不同)有关?我实在是不清楚,望知道的大侠不吝指点,也希望有这方面资料(文章、代码)的朋友贴一些上来。

===================================================
个人觉得和WPARAM,LPARAM这2个消息附加参数有关
tt
re: Big-Endian 和 Little-Endian 两者概念的区别
The concept of endian for CPU architecture also applies to multimedia stream. It's an interesting topic which could easily confuse new entries. FYI!
Laison
re: Big-Endian 和 Little-Endian 两者概念的区别
为什么有大/小前端, 就是因为字节顺序啊. 
而字节顺序当然就是因为我们处理时常以字节为单元. 
而WORD的定义是与内存有关的. 

比如一个外部设备有32位的寄存器, 存放4个字节的数据, 而总线是8位的, 所以他送给CPU时就是一个字节一个字节的, 那这时在BIG/LITTLE里的系统里收到的字节顺序就不一样了. 但是在DS里说的是每个比特的作用, 所以你要定位到准确的比特位, 当然就行区分是CPU和外设分别是按什么方式存储了.

发表评论
切换编辑模式