分类: C/C++
2009-09-25 00:16:22
已经有太多的文章介绍Big Endian和Little Endian了,不过还是想在这里罗嗦几句,算是作为学习字节序的笔记。
早在学校的时候,初次接触嵌入式的时候就开始听说过字节序,了解到Big Endian和Little Endian,不过一直以来对两者都是混淆不清。说实在的,要把这两个分清,还真的是不容易。有很多种说法来帮助我们了解他们的分别,例如Big Endian被认为是最符合我们书写习惯的字节序;为什么这么说呢?大家可以想想一个整数的写法:0x11223344,最高位往往是写在最前面的,再看看整数在Big Endian计算机中的存储模式:
低地址 高地址
----------------------------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 11 | 22 | 33 | 44 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
是不是正好和我们的书写顺序一致。再比如Big Endian就是最有意义的字节在低地址,看看上面的表示方法,不难理解这一点。虽然有这诸多理解方法,不过要真正记住还是得靠平常的不停接触,真正理解其含义才能真正记住。
字节序其实也就是字节在内存中的排放顺序,没有太多的深层含义,只是由于不同的计算机体系结构采用了不同的方式,才导致了今天的麻烦出现。简而言之,Big Endian就是在内存中表示一个整数的各个字节,从最高位开始存放;而Little Endian则正好与之相反,从最低位开始存放。例如0x0D0C00B0A整数在不同的计算机中存储方式如下:
adr: z z+1 z+2 z+3
mem: 0D 0C 0B 0A // big endian
mem: 0A 0B 0C 0D // little endian
从上面的存储方式可以分析到,当进行指针映射时,上述方式的差异相当明显。加入L是一个整数,其值为0x0D0C0B0A,那么char c = *(char *)&L,c在以PowerPC为代表的Big Endian型计算机中是0x0D,而在以X86架构为代表的Little Endian型计算机中则是0x0A。由于这种差别,我们在编码时需要格外注意,特别是在PowerPC型计算机中,因为c = L,按照通常的做法,c = 0x0A,然而按照地址取值得到的是0x0D,与通常的理解是不一致的,这也导致嵌入式开发中出现了很多奇怪的问题,最终发现原因就在于此。举个例子:
void BSP_GetSubBoardType(int chipNum, char *type) |
上面的代码在X86架构的计算机下可能运行成功,然而在PowerPC架构的计算机下showMessage永远不会打印,原因在于type = 0x05yyyyyy,所以type永远不可能等于0x05.
不过上面的不同也给我们检验计算机是big Endian还是Little Endian提供了方法,例如下面的代码就可以用来进行判断:
int isBigEndian() |