大小端字节序_第1页
大小端字节序_第2页
大小端字节序_第3页
大小端字节序_第4页
大小端字节序_第5页
已阅读5页,还剩4页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 字节序 大端 小端分类: 嵌入式2012-11-19 09:24 213人阅读 评论(0) 收藏 举报在各种计算机体系结构中,对于字节、字等的存储机制有所不同,因而引发了计算机通信领 域中一个很重要的问题,即通信双方交流的信息单元(比特、字节、字、双字等等)应该以什么样的顺序进行传送。如果不达成一致的规则,通信双方将无法进行正 确的编/译码从而导致通信失败。目前在各种体系的计算机中通常采用的字节存储机制主要有两种:Big-Endian和Little-Endian,下面先 从字节序说起。 一、什么是字节序字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字

2、节的数据当然就无需谈顺序的问题了)。其实大部分人在实际的开 发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。在所有的介绍字节序的文章中都会提到字 节序分为两类:Big-Endian和Little-Endian,引用标准的Big-Endian和Little-Endian的定义如下:a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协

3、议中使用的字节序通常称之为网络字节序。1.1 什么是高/低地址端首先我们要知道我们C程序映像中内存的空间布局情况:在C专 家编程中或者Unix环境高级编程中有关于内存空间布局情况的说明,大致如下图:- 最高内存地址 0xffffffff栈底栈栈顶-NULL (空洞) -堆-未初始 化的数据- 统称数据段初始化的数据-正 文段(代码段)- 最低内存地址 0x00000000以上图为例如果我们在栈 上分配一个unsigned char buf4,那么这个数组变量在栈上是如何布局的呢?看下图:栈底 (高地址)-buf3 buf2buf1buf0-栈顶 (低地址)1.2 什么是高/低字节现在我们弄清了

4、高/低地址,接着考虑高/低字节。有些文章中称低位字节为最低有效位,高位字节为最高有效位。如果我们有一个32位无符号整型0x12345678,那么高位是什么,低位又是什么呢? 其实很简单。在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。高/低地址端和高/低字节都弄清了。我们再来回顾 一下Big-Endian和Little-Endian的定义,并用图示说明两种字节序:以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用u

5、nsigned char buf4来表示value:Big-Endian: 低地址存放高位,如下图:栈底 (高地址)-buf3 (0x78) - 低位buf2 (0x56)buf1 (0x34)buf0 (0x12) - 高位-栈顶 (低地址)Little-Endian: 低地址存放低位,如下图:栈底 (高地址)-buf3 (0x12) - 高位buf2 (0x34)buf1 (0x56)buf0 (0x78) - 低位-栈 顶 (低地址) 二、各种Endian2.1 Big-Endian计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最重要字节(MSB)存放在最低端的地址 上。采用

6、这种机制的处理器有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 |+-+图 2:Big-

7、Endian的bit序列编码方式2.2 Little-Endian计算机体系结构中 一种描述多字节存储顺序的术语,在这种机制中最不重要字节(LSB)存放在最低端的地址上。采用这种机制的处理器有PDP-11、VAX、Intel系列 微处理器和一些网络通信设备。该术语除了描述多字节存储顺序外还常常用来描述一个字节中各个比特的排放次序。+-+| 0x12 |<- 0x00000021+-+| 0x34 |<- 0x00000020+-+图3:双字节数0x1234以Little-Endian的方式存在起始地址0x00000020中在 Little-Endian中,对于bit序列中的序号编排

8、和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 |+-+图 4:Little-Endian的bit序列编码方式注2:通常我们说的主机序(Host Order)就是遵循Little-Endian规则。所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序 (Little-Endian)和网络序(Big-Endian)的转换。注3:正因为这两种机制对于同一bit序列的序号编排方

9、式恰 恰相反,所以现代英汉词典中对MSB的翻译为“最高有效位”欠妥,故本文定义为“最重要的bit/byte”。2.3 Middle-Endian除了Big-Endian和Little-Endian之外的多字节存储顺序就是Middle- Endian,比如以4个字节为例:象以3-4-1-2或者2-1-4-3这样的顺序存储的就是Middle-Endian。这种存储顺序偶尔会在一些小 型机体系中的十进制数的压缩格式中出现。嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用 Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-en

10、dian模式对操作数的存放方式是从高字节到低字节。 32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:内存 地址0x40000x40010x40020x4003存放内容0x780x560x340x12 而在Big- endian模式CPU内存中的存放方式则为:内存地址0x40000x40010x40020x4003存放内容0x120x340x560x78 三、Big-Endian和Little-Endian优缺点Big-Endian优点:靠首先提取高位字节,你总是可以由看看在偏移位置为0的字节来确定这个数字是 正数还

11、是负数。你不必知道这个数值有多长,或者你也不必过一些字节来看这个数值是否含有符号位。这个数值是以它们被打印出来的顺序存放的,所以从二进制到十进制的函数特别有效。因而,对于不同要求的机器,在设计存取方式时就会不同。Little-Endian优点:提取一个,两个,四个或者更长字节数据的汇编指令以与其他所有格式相同的方式进行:首先在偏移地址为0的地方提取最低位的字节,因为地址偏移和字节数是一对 一的关系,多重精度的数学函数就相对地容易写了。如果你增加数字的值,你可能在左边增加数字(高位非指数函数需要更多的数字)。因此, 经常需要增加两位数字并移动存储器里所有Big-endian顺序的数字,把所有数向

12、右移,这会增加计算机的工作量。不过,使用Little- Endian的存储器中不重要的字节可以存在它原来的位置,新的数可以存在它的右边的高位地址里。这就意味着计算机中的某些计算可以变得更加简单和快速。四、如何检查处理器是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.

13、b = 1); /*return 1 : little-endian, return 0:big-endian*/ 五、Big-Endian和Little-Endian转 换 现有的平台上Intel的X86采用的是Little-Endian,而像 Sun的SPARC采用的就是Big-Endian。那么在跨平台或网络程序中如何实现字节序的转换呢?这个通过C语言的移位操作很容易实现,例如下面的 宏:#if defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)#define htons(A) (A)#define htonl(A) (A)#de

14、fine 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) | (ui

15、nt32)(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." 网络字节顺序1、字节内的比特位不受这种顺序的影响比如一个字节 1000 0000 (或表示为十六进制 80H)不管是什么顺序其内存中的表示法都是这样。 2、大于1个字节的数据类

16、型才有字节顺序问题比如 Byte A,这个变量只有一个字节的长度,所以根据上一条没有字节顺序问题。所以字节顺序是“字节之间的相对顺序”的意思。3、大于1个字节的数据类型的字节顺序有两种比如 short B,这是一个两字节的数据类型,这时就有字节之间的相对顺序问题了。网络字节顺序是“所见即所得”的顺序。而Intel类型的CPU的字节顺序与此相反。比如上面的 short B=0102H(十六进制,每两位表示一个字节的宽度)。所见到的是“0102”,按一般数学常识,数轴从左到右的方向增加,即内存地址从左到右增加的话,在内存中这个 short B的字节顺序是:01 02这就是网络字节顺序。所见到的顺序

17、和在内存中的顺序是一致的!假设通过抓包得到网络数据的两个字节流为:01 02而相反的字节顺序就不同了,其在内存中的顺序为:02 01如果这表示两个 Byte类型的变量,那么自然不需要考虑字节顺序的问题。如果这表示一个 short 变量,那么就需要考虑字节顺序问题。根据网络字节顺序“所见即所得”的规则,这个变量的值就是:0102假设本地主机是Intel类型的,那么要表示这个变量,有点麻烦:定义变量 short X,字节流地址为:pt,按顺序读取内存是为x=*(short*)pt);那么X的内存顺序当然是 01 02按非“所见即所得”的规则,这个内存顺序和看到的一样显然是不对的,所以要把这两个字节

18、的位置调换。调换的方法可以自己定义,但用已经有的API还是更为方便。网络字节顺序与主机字节顺序NBO与HBO 网络字节顺序NBO(Network Byte Order):按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。主机字节顺序(HBO,Host Byte Order):不同的机器HBO不相同,与CPU设计有关计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就需要进行转换。 htonl()简述: 将主机的无符号长整形数转换成网络字节顺序。 #include <winsock.h> u_long PASCAL FAR htonl( u_long hostlong); hostlong:主机字节顺序表达的32位数。注释: 本函数将一个32位数从主机字节顺序转换成网络字节顺序。返回值: htonl()返回一个网络字节顺序的值。inet_ntoa()简述:将网络地址转换成“

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论