什么是Little Endian和Big Endian?(Endianness:字节序、端序、尾序)

2021年9月18日 6点热度 0条评论 来源: 王大雄_

缅怀先驱:提出字节序概念的以色列裔计算机科学家Danny Cohen1,于2019-08-22病逝,享年81岁2

目录

名词释义

Endianness译作字节顺序,又称端序、尾序、尾端序。目前主要在存储或者网络传输场景中,用于约定多字节数据的存储或发送顺序。

字节顺序有两种格式:

  • LITTLE-ENDIAN:小字节序,又称低字节序、小端序、小尾序、小尾端
    可速记为:高位高存
  • BIG-ENDIAN:大字节序,又称高字节序、大端序、大尾序、大尾端
    可速记为:高位低存

概念由来

计算机中数据都是按字节表达、每个字节固定8 bit。当数据较长时,我们会用多个字节来表示数据,如int数值需要4个字节。

多个字节要存储或者网络传输时,调用方/发送方和存储器/接收方势必要约定一个相同的顺序,才能保证数据的含义能被对方正确理解。

比如0xb1b2b3b4这个16进制的int值,一共4个字节。如果发送时按照0xb10xb20xb30xb4的顺序发送,而接收时认为发送方是按相反顺序返送,则会任务接收到的数据是0xb4b3b2b1,这就出现理解不一致。

在早期的计算机体系结构中,因为多字节存储和传输顺序并没有统一规则,上面的场景经常出现,尤其是网络通信非常困难。而对“网络传输中哪种字节排序更合适”的争论一时沸反盈天,已经脱离技术本身的考虑,实际的情况却迟迟得不到改善。

Danny Cohen认为:技术角度并不关心选择哪种字节顺序,重要的是行业需要统一的标准、大家坚持下去。于是在1980年由IETF发表的《论圣战与和平诉求》(On Holy Wars and a Plea for Peace)一文中,他引用了《格列佛游记》中的典故,并使用类似文中概念的little-endianbig-endian,分别表示小端序和大端序。自此这个概念被广泛采用。

Endianness词根Endian出自Jonathan Swift的《格列佛游记》,原文如下:

“…我下面要告诉你的是,Lilliput和Blefuscu这两大强国在过去的三十六个月里一直在苦战。战争开始时由于一下原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端(big-end),可是当今皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了,因此他的父亲,当时的皇帝,就下了一道赦令,命令全体臣民吃鸡蛋是打破鸡蛋较小的一端(little-end),违令者重罚。老百姓们对这项命令极为反感。历史告诉我们,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。这些判断大多都是由Blefuscu的王国大臣们煽动起来的。叛乱平息后,流亡的人总是逃到那个帝国区寻求避难。据统计,先后几次有一万一千人情愿受死也不肯去打破鸡蛋较小的一端。关于这一争端,曾出版过几百本大部著作,不过大端派(big-endians)的书一直是受禁的,法律也规定该派的任何人不得做官。"

鸡蛋从哪头打破,怎么会有哪种更合适呢?对个人生活和社会发展又有什么意义呢?Swift写这段故事,其实是讽刺当时法国和英国的时政,认为真正重要的事情得不到关注、而在一些毫无意义的事情上争论不休。

这就是大端序和小端序的由来。下面介绍下两种排序的具体原理。

设计原理

我们假设有一个int0xb1b2b3b4(0x前缀代表16进制,共4个字节),要存入0x0000开头的内存地址(实际地址比这个要长,这里仅用作演示)。

那么两种规则的存放方式对比如下:

规则 内存
0x0000
内存
0x0001
内存
0x0002
内存
0x0003
big-endian 0xb1 0xb2 0xb3 0xb4
little-endian 0xb4 0xb3 0xb2 0xb1

上表体现了大端序和小端序的形式和区别,可以概括如下:

  • big-endian:高位字节存储在内存低位,简单理解为高(大)位字节(高位代表2的更大指数,数值也更大)先出现。
  • little-endian:高位字节存储在内存高位,简单理解为低(小)位字节先出现。

应用场景

NBO(Net Bytes Order)

网络字节序,普遍理解为TCP/IP协议中使用的字节序。
Danny Cohen当时确定的就是网络层面的字节序规则,最终TCP/IP各层协议统一采用Big-Endian

HBO(Host Bytes Order)

个人对处理器不甚了解,以下文字来自网络。

在现代“冯.诺依曼体系结构”的计算机中,数据都是采用二进制来存储、以字节(Byte)为单位、每个字节包含8位二进制数字(8 bits)。
目前有两大阵营,那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用Big-Endian方式存储数据,而x86系列则采用Little-Endian方式存储数据。

大端和小端的形成有其历史原因,我们在理解的基础上,要明白发展才是硬道理。
得益于高级语言的发展,在现在的软件开发基本不需关心字节序(除非是socket编程),如Java这类跨平台移植的语言由虚拟机屏蔽了字节序问题。

JAVA虚拟机中多字节类型数据的存放顺序,也就是JAVA字节序是Big-Endian
可参考资料:

以上就是对little-endianbig-endian的全部介绍。

内存对齐有兴趣的朋友,可参考下面文章:

待更新:

  • 为什么一个字节定义为8 bit,定义长一些、足够存储最大的数据不就行了吗?
  • Java处理字节序的具体实现是怎么,如何将bit/byte输出为最终数据?
  • 开发中常见的数据检索、内存匹配等操作,是如何进行的、字节序如何运作?
  1. https://en.wikipedia.org/wiki/Danny_Cohen_(computer_scientist) ↩︎

  2. https://www.oschina.net/news/109269/danny-cohen-has-died ↩︎

    原文作者:王大雄_
    原文地址: https://blog.csdn.net/zgdwxp/article/details/103049032
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。