Chinaunix首页 | 论坛 | 博客
  • 博客访问: 61574
  • 博文数量: 6
  • 博客积分: 500
  • 博客等级: 下士
  • 技术积分: 146
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-23 14:35
文章分类
文章存档

2012年(3)

2009年(3)

我的朋友

分类: C/C++

2009-09-25 00:16:22

已经有太多的文章介绍Big EndianLittle Endian了,不过还是想在这里罗嗦几句,算是作为学习字节序的笔记。

早在学校的时候,初次接触嵌入式的时候就开始听说过字节序,了解到Big EndianLittle 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 *)&Lc在以PowerPC为代表的Big Endian型计算机中是0x0D,而在以X86架构为代表的Little Endian型计算机中则是0x0A。由于这种差别,我们在编码时需要格外注意,特别是在PowerPC型计算机中,因为c = L,按照通常的做法,c = 0x0A,然而按照地址取值得到的是0x0D,与通常的理解是不一致的,这也导致嵌入式开发中出现了很多奇怪的问题,最终发现原因就在于此。举个例子:

void BSP_GetSubBoardType(int chipNum, char *type)
{
    *type = 0x05;
}
void process()
{
    int type = 0;
    BSP_GetSubBoardType(0, &type);
    if(0x05 == type)
    {
        showMessage();
    }
}

上面的代码在X86架构的计算机下可能运行成功,然而在PowerPC架构的计算机下showMessage永远不会打印,原因在于type = 0x05yyyyyy,所以type永远不可能等于0x05.

不过上面的不同也给我们检验计算机是big Endian还是Little Endian提供了方法,例如下面的代码就可以用来进行判断:

int isBigEndian()
{
    int value = 0x11223344;
    char *pchar;

    pchar = (char *)&value;
    if(0x11 == *pchar)
        return 1;
    else if(0x44 == *pchar)
        return 0;
    else
        return -1;
}

 

阅读(1646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~