什么是Little Endian Big Endian[转载]
2008-10-26 20:51
274 查看
摘自:http://hi.baidu.com/microking2007/blog/item/7d58258daf571314b31bbae6.html
2008-07-31 08:30
2008-07-31 08:30
Endianness 的问题实质就是关于计算机如何存储大的数值的问题。 我们知道一个基本存储单元可以保存一个字节,每个存储单元对应一个地址。对于大于十进制255(16进制0xff)的整数,需要多个存储单元。例如,4660对应于0x1234,需要两个字节。不同的计算机系统使用不同的方法保存这两个字节。在我们常用的PC机中,低位的字节0x34保存在低地址的存储单元,高位的字节0x12保存在高地址的存储单元;而在Sun工作站中,情况恰恰相反,0x34位于高地址的存储单元,0x12位于低地址的存储单元。前一种就被称为Little Endian,后一种就是Big Endian。 如何记住这两种存储模式?其实很简单。首先记住我们所说的存储单元的地址总是由低到高排列。对于多字节的数值,如果先见到的是低位的字节,则系统就是Little Endian的,Little 就是"小,少"的意思,也就对应"低"。相反就是Big Endian,这里 Big "大"对应"高"。 为了加深对Endianness的理解,让我们来看下面的C程序例子:
所有计算机处理器都必须在这两种Endian间作出选择。但某些处理器(如MIPS和IA-64)支持两种模式,可由编程者通过软件或硬件设置一种Endian。以下是一个处理器类型与对应的Endian的简表: 纯Big Endian: Sun SPARC, Motorola 68000,Java Virtual Machine Bi-Endian, 运行Big Endian模式: MIPS运行IRIX, PA-RISC,大多数Power和PowerPC系统 Bi-Endian, 运行Little Endian模式: MIPS 运行Ultrix,大多数DEC Alpha, IA-64运行Linux Little Endian: Intel x86,AMD64,DEC VAX 如何在程序中检测本系统的Endianess?可调用下面的函数来快速验证,如果返回值为1,则为Little Endian;为0则是Big Endian: int testendian() { int x = 1; return *((char *)&x); } Endianness对于网络通信也很重要。试想当Little Endian系统与Big Endian的系统通信时,如果不做适当处理,接收方与发送方对数据的解释将完全不一样。比如对以上C程序段中的变量d,Little Endian发送方发出11 22 33 44四个字节,Big Endian接收方将其转换为数值0x11223344。这与原始的数值大相径庭。为了解决这个问题,TCP/IP协议规定了专门的"网络字节次序",即无论计算机系统支持何种Endian,在传输数据时,总是数值最高位的字节最先发送。从定义可以看出,网络字节次序其实是对应Big Endian的。 为了避免因为Endianness造成的通信问题,及便于软件开发者编写易于平台移植的程序,特别定义了一些C语言预处理的宏来实现网络字节与主机字节次序之间的相互转换。htons()和htonl()用来将主机字节次序转成网络字节次序,前者应用于16位无符号数,后者应用于32位无符号数。ntohs()和ntohl()实现反方向的转换。这四个宏的原型定义可参考如下(Linux系统中可在netinet/in.h文件里找到):#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?
- 什么是Big Endian和Little Endian?
- 【转载】什么才是真正的休息
- 转载:什么才是真正的 RESTful 架构
- 大端(Big Endian)、小端(Little Endian)
- IOS 开发环境,证书和授权文件是什么?[转载]
- 什么是代数(转载)
- 【引用】『转』【大端(Big Endian)与小端(Little Endian)简介】
- Java中long和Long有什么区别 (转载)
- Big Endian 和 Little Endian
- 京东今天还在用 .NET 架构的原因是什么? (转载)
- socket 通信 Windos 和 Linux之间 Big endian 和 little endian的转换策略
- 域名绑定和域名解析(DNS)有什么不同?(转载)
- 艾伟_转载:[一步一步MVC]第六回:什么是MVC(上)?
- 什么是BI[转载]
- little endian和big endian
- 小端存储(little Endian)大端存储(big Endian)
- (转载)标准库:Allocator能做什么?
- \t\tfedora 10 wheel组有什么用?(转载)
- 好文转载—程序员在工作中会追求什么?