版权声明:本文为博主原创文章,遵循 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. eclipse 的安装

    打开eclipse官网 https://www.eclipse.org/ 点击此处 再点击 最后点击下载 然后一路下一步安装即可 添加中文语言包 打开eclipse官网 https://www.ecl ...

  2. 解决JRebel对myBatis Mapper 失效的问题

    解决JRebel对myBatis Mapper 失效的问题 在之前的文章中介绍了JRebel这个插件的使用和优势,虽然它对配置文件的改动的热更新是生效的,但是mybatis的mapper文件的改动却无 ...

  3. linux-发送文件夹rsync -avz salt-发送文件/文件夹

    linux下同步文件夹 rsync -avz /local_position/test_dir/ root@192.168.1.165:/target_position # ps:rsync -avz ...

  4. 【zabbix监控问题】记录zabbix控制面板报错及日志报错的解决方法

    问题1: 上图是我已经解决了的截图.在百度查询的资料中,说是把zabbix_agentd.conf文件中server监听的主机127.0.0.1去掉,但是我去掉之后问题仍然没有解决,最后在这篇博客上发 ...

  5. 简单的权限管理php

    转发自https://www.cnblogs.com/shenzikun1314/p/6604867.html#4262295 首先,要明白的基础理论是用户,角色,权限之间的关系是一对多,还是多对多. ...

  6. springcloud vue.js 微服务分布式 前后分离 集成代码生成器 shiro权限 activiti工作流

    1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.service等完整模块2. ...

  7. 编译原理之非确定的自动机NFA确定化为DFA

    1.设有 NFA M=( {0,1,2,3}, {a,b},f,0,{3} ),其中 f(0,a)={0,1}  f(0,b)={0}  f(1,b)={2}  f(2,b)={3} 画出状态转换矩阵 ...

  8. Struts2.0

    流程详解:   配置详解:   constant  (常用常量配置) 使用Struts2 框架 ,先要导入Struts2 需要的jar 包 , 通过配置中央控制器 以及web.xml 来实现  Str ...

  9. 拷贝本地文件到docker容器内部

    #复制本地目录的xxx到镜像内部并且为xxx docker cp /home/xxx targetImage:/home/xxx

  10. liunxCPU和内存,磁盘等资源

    1.Screen是一款由GNU计划开发的用于命令行终端切换的自由软件.用户可以通过该软件同时连接多个本地或远程的命令行会话,并在其间自由切换.GNU Screen可以看作是窗口管理器的命令行界面版本. ...