版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/kingmax54212008/article/details/46043179

一、引子

  在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了

计算机通信领域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、

字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方

将无法进行正确的编/译码从而导致通信失败。目前在各种体系的计算机中通常采

用的字节存储机制主要有两种:

big-edian和little-endian。本文简要描述这两种存储机制的来历、特点和区别。

  

  为了叙述方便,下面先对本文中将要用到的两个术语做简单的定义。

1、MSB

MSB是Most Significant Bit/Byte的首字母缩写,通常译为最重要的位或者最

重要的字节。它通常用来表明在一个bit序列(如一个byte是8个bit组成的一个序

列)或者一个byte序列(如word是两个byte组成的一个序列)中对整个序列取值影

响最大的那个bit/byte。

2、LSB

LSB是Least Significant Bit/Byte的首字母缩写,通常译为最不重要的位或

者最不重要的字节。它通常用来表明在一个bit序列(如一个byte是8个bit组成的

一个序列)或者一个byte序列(如word是两个byte组成的一个序列)中对整个序

列取值影响最小的那个bit/byte。

二、endian的由来

1、Definition

endian: The ordering of bytes in a multi-byte number.

定义:在计算机系统体系结构中用来描述在多字节数中各个字节的存储顺序。

2、Etymology

The term comes from Swift's "Gulliver's Travels" via the famous paper

"On Holy Wars and a Plea for Peace" by Danny Cohen, USC/ISI IEN 137,

1980-04-01.

The Lilliputians, being very small, had correspondingly small political

problems. The Big-Endian and Little-Endian parties debated over whether

soft-boiled eggs should be opened at the big end or the little end.[From:

Free On-Line Dictionary Of Computing or Jargon File]

词源:据Jargon File记载,endian这个词来源于Jonathan

Swift在1726年写的讽刺小说 "Gulliver's Travels"(《格利佛游记》)。该小说

在描述Gulliver畅游小人国时碰到了如下的一个场景。在小人国里的小人因为非常

小(身高6英寸)所以总是碰到一些意想不到的问题。有一次因为对水煮蛋该从大的

一端(Big-End)剥开还是小的一端(Little-End)剥开的争论而引发了一场战争,

并形成了两支截然对立的队伍:支持从Big-End剥开的人Swift就称作Big-Endians

而支持从Little-End剥开的人就称作Little-Endians……(后缀ian表明的就是支持

某种观点的人:-)。Endian这个词由此而来。

  

  1980年,Danny Cohen在其著名的论文"On Holy Wars and a Plea for Peace"

中为了平息一场关于在消息中字节该以什么样的顺序进行传送的争论而引用了该词。

该文中,Cohen非常形象贴切地把支持从一个消息序列的MSB开始传送的那伙人叫做

Big-Endians,支持从LSB开始传送的相对应地叫做Little-Endians。此后Endian这

个词便随着这篇论文而被广为采用。

三、各种endian

1、big-endian

A computer architecture in which, within a given multi-byte numeric

representation, the most significant byte has the lowest address (the

word is stored "big-end-first").  

Most processors, including the IBM 370 family, the PDP-10, the

Motorola microprocessor families, and most of the various RISC designs

current in mid-1993, are big-endian. [From: Free On-Line Dictionary Of

Computing or Jargon File]

big-endian:计算机体系结构中一种描述多字节存储顺序的术语,在这种机制

中最重要字节(MSB)存放在最低端的地址上。采用这种机制的处理器有IBM3700系

列、PDP-10、Mortolora微处理器系列和绝大多数的RISC处理器。

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

| 0x34 |<-- 0x00000021

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

| 0x12 |<-- 0x00000020

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

图1:双字节数0x1234以big-endian的方式存在起始地址0x00000020中

在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0x8B8A为

例):

bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

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

val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |

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

^ 0x8B 0x8A ^

MSB LSB

图2:Big-Endian的bit序列编码方式

注1:通常在TCP/IP协议栈所说的网络序(Network Order)就是遵循Big-Endian

规则。在TCP/IP网络通信中,通信双方把消息按照如图2的方式进行编码,然后按

从MSB(Bit0)到LSB的顺序在网络上传送。

2、little-endian

   A computer architecture in which, within a given

16- or 32-bit word,bytes at lower addresses have lower significance (the

word is stored "little-end-first"). The PDP-11 and VAX families of

computers and Intel microprocessors and a lot of communications and

networking hardware are little-endian.

The term is sometimes used to describe the ordering of units other

than bytes; most often, bits within a byte. [From: Free On-Line Dictionary

Of Computing or Jargon File]

little-endian:计算机体系结构中一种描述多字节存储顺序的术语,在这种机

制中最不重要字节(LSB)存放在最低端的地址上。采用这种机制的处理器有PDP-11、

VAX、Intel系列微处理器和一些网络通信设备。该术语除了描述多字节存储顺序外

还常常用来描述一个字节中各个比特的排放次序。

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

| 0x12 |<-- 0x00000021

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

| 0x34 |<-- 0x00000020

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

图3:双字节数0x1234以little-endian的方式存在起始地址0x00000020中

在Little-Endian中,对于bit序列中的序号编排和Big-Endian刚好相反,其方

式如下(以双字节数0x8B8A为例):

bit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

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

val | 1 0 0 0 1 0 1 1 | 1 0 0 0 1 0 1 0 |

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

^ 0x8B 0x8A ^

MSB LSB

图4:Little-Endian的bit序列编码方式

注2:通常我们说的主机序(Host Order)就是遵循Little-Endian规则。所以

当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机

序(Little-Endian)和网络序(Big-Endian)的转换。

注3:正因为这两种机制对于同一bit序列的序号编排方式恰恰相反,所以《现

代英汉词典》中对MSB的翻译为“最高有效位”欠妥,故本文定义为“最重要的bit

/byte”。

3、middle-endian:

Neither big-endian nor little-endian. Used of

perverse byte orders such as 3-4-1-2 or 2-1-4-3, occasionally found in

the packed decimal formats of some minicomputer manufacturers.[From:

Free On-Line Dictionary Of Computing or Jargon File]

  middle-endian:除了big-endian和little-endian之外的多字节存储顺序就是

middle-endian,比如以4个字节为例:象以3-4-1-2或者2-1-4-3这样的顺序存储的

就是middle-endian。这种存储顺序偶尔会在一些小型机体系中的十进制数的压缩格

式中出现。

四、收尾

要详细解释这两种编码顺序已经超出本文所涉及的内容,如果你有兴趣的话可

以参考上面提及的Danny Cohen的论文("On Holy Wars and a Plea for Peace"),

该论文详细的描述了这两种编码顺序的历史、所基于的数学理论和各自拥护者争论

的焦点等知识,绝对可以大饱你打破沙锅问到底的内心需要。

什么是字节序?

  字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺 序的问题了)。其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。在所有的介绍字节序 的文章中都会提到字节序分为两类:Big-Endian和Little-Endian。引用标准的Big-Endian和Little-Endian的定 义如下:

a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

PS:有些文章中称低位字节为最低有效位,高位字节为最高有效位。

Big endian means that the most significant byte of any multibyte data field is stored at the lowest memory address, which is also the address of the larger field.

Little endian means that the least significant byte of any multibyte data field is stored at the lowest memory address, which is also the address of the larger field.

什么是高/低地址端 什么是高/低字节

  首先我们要知道我们C程序映像中内存的空间布局情况:在《C专家编程》中或者《Unix环境高级编程》中有关于内存空间布局情况的说明,大致如下图:

----------------------- 最高内存地址 0xffffffff

| 栈底

.

. 栈

.

栈顶

|

|

|/

NULL (空洞)

/|

|

未初始化的数据

----------------(统称数据段)

初始化的数据

正文段(代码段)

----------------------- 最低内存地址 0x00000000

以上图为例如果我们在栈上分配一个unsigned char buf[4],那么这个数组变量在栈上是如何布局的呢?看下图:

栈底 (高地址)

buf[3] 

buf[2]

buf[1]

buf[0]

栈顶 (低地址)

现 在我们弄清了高/低地址,接着考虑高/低字节。如果我们有一个32位无符号整型0x12345678,那么高位是什么,低位又是什么呢?其实很简单。在十 进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。

高/低地址端和高/低字节都弄清了。我们再来回顾一下Big-Endian和Little-Endian的定义,并用图示说明两种字节序:

以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value:

Big-Endian: 低地址存放高位,如下图:

栈底 (高地址)

buf[3] (0x78) -- 低位

buf[2] (0x56)

buf[1] (0x34)

buf[0] (0x12) -- 高位

栈顶 (低地址)

Little-Endian: 低地址存放低位,如下图:

栈底 (高地址)

buf[3] (0x12) -- 高位

buf[2] (0x34)

buf[1] (0x56)

buf[0] (0x78) -- 低位

栈顶 (低地址)

现有的平台上Intel的X86采用的是Little-Endian,而像Sun的SPARC采用的就是Big-Endian。那么在跨平台或网络程序中如何实现字节序的转换呢?这个通过C语言的移位操作很容易实现,例如下面的宏:

#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)

#define htons(A)   (A)
#define htonl(A)    (A)
#define ntohs(A)   (A)
#define ntohl(A)    (A) #elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN) #define htons(A)    ((((uint16)(A) & 0xff00) >> 8) | \
                              (((uint16)(A) & 0x00ff) << 8))
#define htonl(A)    ((((uint32)(A) & 0xff000000) >> 24) | \
                             (((uint32)(A) & 0x00ff0000) >> 8) | \
                             (((uint32)(A) & 0x0000ff00) << 8) | \
                             (((uint32)(A) & 0x000000ff) << 24))
#define ntohs htons
#define ntohl htohl #else #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both." #endif

如何检查处理器是big-endian还是little-endian?

  由于联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。例如:

 int checkCPUendian(){
       union {
            unsigned int a;
            unsigned char b;            
       }c;
       c.a = 1;
       return (c.b == 1);       
  }  /*return 1 : little-endian, return 0:big-endian*/
 ``` ————————————————
版权声明:本文为CSDN博主「kingmax54212008」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kingmax54212008/article/details/46043179

ENDIAN的由来及BIG-EDIAN 和LITTLE-ENDIAN(转)的更多相关文章

  1. 【转】go语言的字节序

    原文:http://lihaoquan.me/2016/11/5/golang-byteorder.html 这个人的博客写的不错,品质也比较高. 我应该也要有这种精神,这种态度.深入到计算机的世界中 ...

  2. 字符编码笔记:ASCII、Unicode、UTF-8、UTF-16、UCS、BOM、Endian

    转载:http://witmax.cn/character-encoding-notes.html 今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问 ...

  3. 数据在内存中的存储方式( Big Endian和Little Endian的区别 )(x86系列则采用little endian方式存储数据)

    https://www.cnblogs.com/renyuan/archive/2013/05/26/3099766.html 1.故事的起源 “endian”这个词出自<格列佛游记>.小 ...

  4. 关于Big Endian 和 Little Endian

    Big Endian 和 Little Endian 一.字节序 来自:http://ayazh.gjjblog.com/archives/1058846/ 谈到字节序的问题,必然牵涉到两大CPU派系 ...

  5. c#,关于Big Endian 和 Little Endian,以及转换类

    Big Endian:最高字节在地址最低位,最低字节在地址最高位,依次排列. Little Endian:最低字节在最低位,最高字节在最高位,反序排列. 当在本地主机上,无需注意机器用的是Big En ...

  6. write a macro to judge big endian or little endian

    Big endian means the most significant byte stores first in memory. int a=0x01020304, if the cpu is b ...

  7. java代码中存在的Big Endian 和 Little Endian

    Big Endian 和 Little Endian 详解 Java中的Big(Little)-endian问题的一种解决方法 主机序和网络序  很重要很重要 几种ip存放形式 Big-Endian和 ...

  8. MSB与LSB Big Endian Little Endian

    Most Significant Bit, Last(Least) Significant Bit 最高有效位(MSB) 指二进制中最高值的比特.在16比特的数字音频中,其第1个比特便对16bit的字 ...

  9. 字节序:Big Endian 和 Little Endian

    一.字节序 字节序,也就是字节的顺序,指的是多字节的数据在内存中的存放顺序. 在几乎所有的机器上,多字节对象都被存储为连续的字节序列.例如:如果C/C++中的一个int型变量 a 的起始地址是& ...

随机推荐

  1. maven的下载、安装及配置

    一.下载maven 1. maven的下载路径 (1)Apache官网:https://maven.apache.org (2)https://pan.baidu.com/s/1Yvv44ICGSxG ...

  2. composer入门 一些简单常用的命令介绍

    composer是什么 composer是PHP的插件依赖管理工具,我个人感觉和java的Maven.Gradle很类似. Windows OS下安装composer 参考: https://www. ...

  3. java正则表达式大全(常用)

    一.校验数字的表达式 数字:^[-]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数字:^\d{m,n}$ 零和非零开头的数字:^(|[-][-]*)$ 非零开头的最多 ...

  4. Dubbo学习笔记-RPC扩展和本地Mock

    1.Dubbo介绍 Dubbo,一个是一款高性能Java RPC框架.私以为有中文官方文档,就不再重复介绍了 2.RPC扩展-本地存根stub RPC扩展功能:提前效验参数,缓存调用结果,日志记录等等 ...

  5. Go 开发关键技术指南 | 为什么你要选择 GO?(内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 关注"阿里巴巴云原生"公众号,回复 Go 即可查看清晰知识大图! 导读:从问题本身出发,不局限于 Go 语言,探讨服务器中常常遇到的 ...

  6. jvm虚拟机笔记<三> 类文件结构与类加载机制

    java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...

  7. TensorFlow实现图像卷积并可视化示例

    图片尺寸要自己修改. 看起来好像没啥意思,不知道下一步能干什么,先卷了再说.由于weights是随机生成的(tf.random_normal作用:用于从服从指定正太分布的数值中取出随机数),所以每次卷 ...

  8. 分析Android APK-反编译修改打包

    2.2 这个章节的主要作用就是,修改一个别人的app,在里边增加一段自己的广告代码. 2.2.1 UAA 编译修改,工具安装配置之前讲过,无需再赘述.我们找到了一款游戏app的apk, 找到所在的ap ...

  9. 【Beta阶段】第十二周Scrum会议

    [Beta阶段]第十二周Scrum会议 本次会议为第十二周第一次Scrum Meeting,会议对Beta阶段工作进行了总结,针对Beta阶段还未完成的问题进行了讨论. 会议时间为2019.12.3. ...

  10. 如何在linux终端创建文件

    我们都知道可以用mkdir命令创建一个新的目录,但更多时候如果能直接创建一个文件(普通文件)会让人感觉更愉悦:这样就可以不用在去打开一个专门的创建文本文件的软件,然后还要设置文件名,保存路径那样的繁琐 ...