大端小端规则_第1页
大端小端规则_第2页
大端小端规则_第3页
大端小端规则_第4页
大端小端规则_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

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

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

3、网络字节序。1.1什么是高/低地址端首先我们要知道我们C程序映像中内存的空间布局情况:在C专家编程中或者Unix环境高级编程中有矢于内存空间布局情况的说明,大致如下图:最高内存地址Oxffff栈底栈栈顶NULL (空洞)未初始化的数据初始化的数据正文段(代码段)最低内存地址0x0000以上图为例如果我们在栈上分配一个un sig ned char buf4,那么这个数组变量在栈上是如何布局的呢?看下图:栈底(高地址)buf3buf2buf1buf0栈顶(低地址)1 -2什么是高/低字节现在我们弄清了高/低地址,接着考虑高/低字节。有些文章中称低位字节为最低有效位,高位字节为最高有效位。如果我们

4、有一个32位 无符号整型0X,那么高位是什么,低位又是什么呢?其实很简单。在十进制中我们都说靠左边 的是高位,靠右边的是低位,在其他进制也是如此。就拿Ox来说,从高位到低位的字节依次 是Ox12、Ox34、0x56 和 0x78。高/低地址端和高/低字节都弄清了。我们再来回顾一下Big-Endian和Little-En dian的定义,并用图示说明两种字节序:以unsignedintvalue=Ox为例,分别看看在两种字节序下其存储情况 我们可以用 unsigned char buf4来表示 value:Big-E ndian:低地址存放高位,如下图:栈底(高地址)buf3 (0x78)低位b

5、uf2 (0x56)buf1 (0x34)bufO (0x12) 一高位栈顶(低地址)Little-E ndian:低地址存放低位,如下图:栈底(高地址)buf3 (0x12) 一高位buf2 (0x34)buf1 (0x56)buf0 (0x78)低位栈顶(低地址)二、各种 Endian2.1 Big-Endia n计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最重要字节(MSB)存放在最低端的地址上。采用这种机制的处理器有IBM3700系列、PDP-10、Mortolora微处理器系列和绝大多数的RISC处理器。| 0x34 |- 0x00021| 0x12 |- 0x0002

6、0图1双字节数0x1234以Big-Endian的方式存在起始地址0x00020中在Big-Endian中,对于bit序列中的序号编排方式如下(以双字节数0x8B8A为例):bit 0 1 23456789 10 11 12 13 1415val|10001011|10001010图2 : Big-Endian的bit序列编码方式2.2 Little-Endian计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最不重要字节(LSB存放在最低端的地址上。采用这种机制的处理器有PDP-11 VAX In tel系列微处理器和一些网络通信设备。该术语除了描述多字节 存储顺序外 还常常用来描

7、述一个字节中各个比特的排放次序。| 0x12 |- 0x00021| 0x34|-0x00020图3:双字节数0x1234以Little-Endian的方式存在起始地址0x00020中在 Little-Endian中,对于bit序列中的序号编排和Big-Endian刚好相反,其方式如下(以双字节数0X8B8A为例):bit1514 13 12 11 1098765432 1 0val|10001011|10001010|图4 : Little-Endian的bit序列编码方式注2 :通常我们说的主机序(HostOrder)就是遵循Little-Endian规则。所以当两台主机 之间要通过TCP

8、/IP协议进行通信的时候就需要调用相应的函数进行主机序(Little-Endian)和 网络序(Big-Endian)的转换。注3:正因为这两种机制对于同一 bit序列的序号编排方式恰恰相反,所以现代英汉词典中对MSB的翻译为最高有效位”欠妥,故本文定义为最重要的 bit/byte。M2.3 Middle-Endian除了 Big-Endian和Little-Endian之外的多字节存储顺序就是Middle-Endian,比如以4个字节为例:象以3-4-1-2或者2-1-牛3这样的顺序存储的就是Middle-Endian。这种存储 顺序偶尔 会在一些小型机体系中的十进制数的压缩格式中出现。嵌入

9、式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian 模式对操作数的存放方式是从高字节到低字节。32bit宽的数Ox在Little-endianCPU内存中的存放方式(假设从地址0x4000开始存放)为:内存地址0x4000存放内容0x78而在Big- endian模式CPU内存中的存放方式则为:内存地址0x4000存放内容0x12三、Big-Endian 和 Little-Endian 优缺点0x40010x340x40020x560x40030x780x4001

10、0x560x40020x340x40030x12Big-E ndian 优点:靠首先提取高位字节,你总是可以由看看在偏移位置为0的字节来确定这个数字是正数 还是负数。你不必知道这个数值有多长,或者你也不必过一些字 节来看这个数值是否含有符号 位。这个数值是以它们被打印出来的顺序存放的,所以从二进制到十进制的函数特别有效。因 而,对于不同要求的机器,在设计存取方式时就会不同。Little-Endian 优点:提取一个,两个,四个或者更长字节数据的汇编指令以与其他所有格式相同的方式进行:首先在偏移地址为0的地方提取最低位的字节,因为地址偏移和字节数是 一对一的矢系,多重精度的数学函数就相对地容易写

11、了。如果你增加数字的值,你可能在左边增加数字(高位非指数函数需要更多的数字)。因此,经常需要增加两位数字并移动存储器里所有Big-e ndian顺序的数字,把所有数向右移,这会增加计算机的工作量。不过,使用Little- Endian的存储器中不重 要的字节可以存在它原来的位置,新的数可以存在它的右边的高 位地址里。这就意味着计算机 中的某些计算可以变得更加简单和快速。四、如何检查处理器是Big-Endian还是Little-Endian?由于联合体union的存放顺序是所有成员都从低地址开始存放,利用该特性就可以轻松地获得了 CPU对内存采用Little- endian还是Big-endia

12、n模式读写。例如:int checkCPUendian() union unsigned int a;unsigned char b;c; return (c.b = 1); /*return 1 :little-endian, return O:big-endian*/五、Big-Endian 和 Little-Endian 转换现有的平台上In tel的X86采用的是Little-E ndia n,而像Sun的SP ARC采用 的 就是Big-Endiano那么在跨平台或网络程序中如何实现字节序的转换呢?这个通过C语 言的移位操作很容易实现,例如下面的宏:#if defined(BIG_E

13、NDIAN) & !defined(LITTLE_ENDIAN) #define htons(A)(A) #define htonl(A) (A)10/13#define ntohs(A) (A)#define ntohl(A) (A)#elif defined(LITTLE_ENDIAN) & !defined(BIG_ENDIAN)#define htons(A) (uint16)(A) & OxffOO) 8) | (uint16)(A) &0xOOff) 8)#define htonl(A) (uint32)(A) & OxffOOO) 24) | (uint32)(A) & OxOO

14、ffOO) 8) | (uint32)(A) & OxOOffOO) 8) | (uint32)(A) & OxOOOff) 24)#define ntohs htons#define ntohl htohl#else#error “Either BIG ENDIAN or LITTLE ENDIAN must be #defined, but notboth.网络字节顺序1、字节内的比特位不受这种顺序的影响比如一个字节10000 (或表示为十六进制80H)不管是什么顺序其内存中的 表示法都 是这样。2、大于1个字节的数据类型才有字节顺序问题比如Byte A,这个变量只有一个字节的长度,所以根

15、据上一条没有字节顺序问题。所以字 节顺序是“字节之间的相对顺序”的意思。3、大于1个字节的数据类型的字节顺序有两种比如shortB,这是一个两字节的数据类型,这时就有字节之间的相对顺序问题了。网络字节顺序是所见即所得”的顺序。而In tel类型的CPU的字节顺序与此相反。比如上面的short B=0102H十六进制,每两位表示一个字节的宽度)。所见到的是 “0102,”按一般数学常识,数轴从左到右的方向增加,即内存地址从左到右增加的话,在 内存中这个short B的字节顺序是:01 02这就是网络字节顺序。所见到的顺序和在内存中的顺序是一致的!假设通过抓包得到网络数据的两个字节流为:01 02

16、而相反的字节顺序就不同了,其在内存中的顺序为:02 01如果这表示两个Byte类型的变量,那么自然不需要考虑字节顺序的问题。如果这表示一 个short变量,那么就需要考虑字节顺序问题。根据网络字节顺序“所见即所得”的规则, 这个变量的值就是:0102假设本地主机是Intel类型的,那么要表示这个变量,有点麻烦:定义变量shortX,字节流地址为:pt,按顺序读取内存是为x=*(short*)pt);那么X的内存顺序当然是01 02按非“所见即 所得”的规则,这个内存顺序和看到的一样显然是不对的,所以要把这两个字节的位置调 换。调换的方法可以自己定义,但用已经有的API还是更为方便。网络字节顺序

17、与主机字节顺序NBO 与 HBO 网络字节顺序 NBO (Network Byte Order):按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。主机字节顺序(HBO,Host Byte Order):不同的机器HBO不相同,与CPU设计有矢计算机数据存储有两种字节优先顺序:htonl()简述: 将主机的无符号长整形数转换成网络字节顺序。#include ujong PASCAL FAR htonl( u_Jong hostlong);hostlong :主机字节顺序表达的32位数。注释:本函数将一个32位数从主机字节顺序转换成网络字节顺序。返回值:htonlO返回一个网络字节顺序的值。简述:将网络地址转换成“点”隔的字符串格式。#include in :注释:返回值:12 /char b4kc aM

温馨提示

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

评论

0/150

提交评论