little endian和big endian
2009-05-12 11:25
274 查看
1.故事的起源
“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。
我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
2.什么是Big Endian和Little Endian?
在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。
比如某些文件需要在不同平台处理,或者通过Socket通信。这方面我们可以借助ntohl(), ntohs(), htonl(), and htons()函数进行格式转换,
个人补充:一个操作数作htonl或ntohl结果不一定相同,当机器字节序跟网络字节序刚好是仅仅big endian和little endian的区别时是相同的。
3. 如何理解Big Endian和Little Endian
举个例子:
int a = 1;
a这个数本身的16进制表示是0x00 00 00 01
在内存中怎么存储呢?
如果你的CPU是intel x86架构的(基本上就是通常我们说的奔腾cpu),那么就是0x01 0x00 0x00 0x00 , 这也就是所谓的little-endian, 低字节存放在内存的低位.
如果你的CPU是老式AMD系列的(很老很老的那种,因为最新的AMD系列已经是x86架构了), 它的字节序就是big-endian, 其内存存储就是
0x00 0x00 0x00 0x01在内存中从高字节开始存放。
现在世界上绝大多数的CPU都是little-endian。
4. big-endian和little-endian實例
以下是判断字节存储顺序的可移植的C语言代码:
很多人认为掌握这个知识是不必要,其实不然.在网络编程中,TCP/IP统一采用big endian方式传送数据,也就是说,假设现在是在一个字节顺序是little endian的机器上传送数据,要求传送的数据是0XCEFABOBO,那么你就要以0XBOBOFACE的顺序在unsigned int中存放这个数据,只有这样才能保证存放的顺序满足TCP/IP的字节顺序要求.很多时候,需要自己编写应用层的协议,字节顺序的概念在这个时候就显得及其的重要了.
下面给出的是在big endian和little endian中相互转换的代码,C语言强大的位操作的能力在这里显示了出来:
参考资料:<<C: A Reference Manual>>
5.如何判断系统是Big Endian还是Little Endian?
在/usr/include/中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER, __BYTE_ORDER),确定其值。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。一般来说,Little Endian系统BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)为1234,Big Endian系统为4321。大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本质上说,Little Endian还是Big Endian与操作系统和芯片类型都有关系.
轉自:小白的QQ空間。
“endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。
我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。
2.什么是Big Endian和Little Endian?
在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。
比如某些文件需要在不同平台处理,或者通过Socket通信。这方面我们可以借助ntohl(), ntohs(), htonl(), and htons()函数进行格式转换,
个人补充:一个操作数作htonl或ntohl结果不一定相同,当机器字节序跟网络字节序刚好是仅仅big endian和little endian的区别时是相同的。
3. 如何理解Big Endian和Little Endian
举个例子:
int a = 1;
a这个数本身的16进制表示是0x00 00 00 01
在内存中怎么存储呢?
如果你的CPU是intel x86架构的(基本上就是通常我们说的奔腾cpu),那么就是0x01 0x00 0x00 0x00 , 这也就是所谓的little-endian, 低字节存放在内存的低位.
如果你的CPU是老式AMD系列的(很老很老的那种,因为最新的AMD系列已经是x86架构了), 它的字节序就是big-endian, 其内存存储就是
0x00 0x00 0x00 0x01在内存中从高字节开始存放。
现在世界上绝大多数的CPU都是little-endian。
4. big-endian和little-endian實例
以下是判断字节存储顺序的可移植的C语言代码:
/******************************************************************** created: 2006-9-5 filename: test.cpp author: 李创 purpose: 可移植的用于判断存储格式是 little endian还是big ednian的C代码 取自<<C: A Reference Manual>> *********************************************************************/ #include <stdio.h> union { long Long; char Char[sizeof(long)]; }u; int main() { u.Long = 1; if (u.Char[0] == 1) { printf("Little Endian!/n"); } else if (u.Char[sizeof(long) - 1] == 1) { printf("Big Endian!/n"); } else { printf("Unknown Addressing!/n"); } printf("Now, Let's look at every byte in the memory!/n"); for (int i = 0; i < sizeof(long); ++i) { printf("[%x] = %x/n", &u.Char, u.Char); } return 0; }
很多人认为掌握这个知识是不必要,其实不然.在网络编程中,TCP/IP统一采用big endian方式传送数据,也就是说,假设现在是在一个字节顺序是little endian的机器上传送数据,要求传送的数据是0XCEFABOBO,那么你就要以0XBOBOFACE的顺序在unsigned int中存放这个数据,只有这样才能保证存放的顺序满足TCP/IP的字节顺序要求.很多时候,需要自己编写应用层的协议,字节顺序的概念在这个时候就显得及其的重要了.
下面给出的是在big endian和little endian中相互转换的代码,C语言强大的位操作的能力在这里显示了出来:
/******************************************************************** created: 2006-9-5 filename: get32put32.cpp author: 李创 purpose: 在little endian和big ednian之间相互转化数据的演示代码 *********************************************************************/ #include <stdio.h> const unsigned char SIZE_OF_UNSIGNEDINT = sizeof(unsigned int); const unsigned char SIZE_OF_UNSIGNEDCHAR = sizeof(unsigned char); void put_32(unsigned char *cmd, unsigned int data) { int i; for (i = SIZE_OF_UNSIGNEDINT - 1; i >= 0; --i) { cmd = data % 256; // 或者可以: //cmd = data & 0xFF; data = data >> 8; } } unsigned int get_32(unsigned char *cmd) { unsigned int ret; int i; for (ret = 0, i = SIZE_OF_UNSIGNEDINT - 1; i >= 0; --i) { ret = ret << 8; ret |= cmd; } return ret; } int main(void) { unsigned char cmd[SIZE_OF_UNSIGNEDINT]; unsigned int data, ret; unsigned char *p; int i; data = 0x12345678; printf("data = %x/n", data); // 以字节为单位打印出数据 p = (unsigned char*)(&data); for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i) { printf("%x", *p++); } printf("/n"); // 以相反的顺序存放到cmd之中 put_32(cmd, data); for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i) { printf("cmd[%d] = %x/n", i, cmd); } // 再以相反的顺序保存数据到ret中 // 保存之后的ret数值应该与data相同 ret = get_32(cmd); printf("ret = %x/n", ret); p = (unsigned char*)(&ret); for (i = 0; i < SIZE_OF_UNSIGNEDINT; ++i) { printf("%x", *p++); } printf("/n"); return 0; }
参考资料:<<C: A Reference Manual>>
5.如何判断系统是Big Endian还是Little Endian?
在/usr/include/中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER, __BYTE_ORDER),确定其值。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。一般来说,Little Endian系统BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)为1234,Big Endian系统为4321。大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本质上说,Little Endian还是Big Endian与操作系统和芯片类型都有关系.
轉自:小白的QQ空間。
相关文章推荐
- 大端(Big Endian)与小端(Little Endian)详解
- Big Endian 与 Little Endian
- 字节序 big endian 和 little endian
- little endian和big endian
- 写程序判断big endian little endian
- 大端(Big Endian)与小端(Little Endian)详解
- 大端(Big Endian)与小端(Little Endian)详解
- [J2SE]两种字节序:Big Endian和Little Endian
- 大端(Big Endian)与小端(Little Endian)详解
- 判断little endian和big endian
- Big Endian 与 Little Endian
- 字节序Big Endian和Little Endian
- CPU的大端模式(big endian)和小端(little endian)模式
- Big Endian 和 Little Endian
- little endian和big endian的概念解释,判定与用途
- 关于Big Endian 和 Little Endian
- 判断Big Endian 和 Little Endian
- Big Endian 和 Little Endian
- Big Endian 和 Little Endian优劣
- 大端模式Big Endian和小端模式Little Endian以及浮点数在内存中的存储