Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1682236
  • 博文数量: 210
  • 博客积分: 10013
  • 博客等级: 上将
  • 技术积分: 2322
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-25 15:56
文章分类

全部博文(210)

文章存档

2011年(34)

2010年(121)

2009年(37)

2008年(18)

我的朋友

分类: C/C++

2010-07-06 16:43:14

Little endianBig endianCPU存放数据的两种不同顺序。对于整型、长整型等数据类型,Big endian认为第一个字节是最高位字节(按照从低地址到高地址的顺序存放数据的高位字节到低位字节);而Little endian则相反,它认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放数据的低位字节到高位字节)。

Big 从内存地址的低到高位保存数据的从高到底位

Little:从内存地址的低到高位保存数据的从低到高位

内存内容如下:

0x0000

0x0001

0x0002

0x0003

0x12

0x23

0xab

0xcd

如果是big:读出来的内容是0x1234abcd,如果是little读出来的内容是0xcdab3412

0x1234abcd写入:

内存地质

0x0000

0x0001

0x0002

0x0003

Big

0x12

0x23

0xab

0xcd

Little

0xcd

0xab

0x34

0x12

一般来说,x86系列CPU都是little-endian的字节序,PowerPC通常是Big endian,还有的CPU能通过跳线来设置CPU工作于Little endian还是Big endian模式。

解答这个问题的方法只能是将一个字节(CHAR/BYTE类型)的数据和一个整型数据存放于同样的内存开始地址,通过读取整型数据,分析CHAR/BYTE数据在整型数据的高位还是低位来判断CPU工作于Little endian还是Big endian模式。得出如下的答案:

typedef unsigned char BYTE;

int main(int argc, char* argv[])

{

       unsigned int num,*p;

        p = #

       num = 0;

 

    *(BYTE *)p = 0xff;

      

       if(num == 0xff)

       {

              printf("The endian of cpu is little\n");

       }

       else    //num == 0xff000000

       {

              printf("The endian of cpu is big\n");

       }

       return 0;

}

除了上述方法(通过指针类型强制转换并对整型数据首字节赋值,判断该赋值赋给了高位还是低位)外,还有没有更好的办法呢?我们知道,union的成员本身就被存放在相同的内存空间(共享内存,正是union发挥作用、做贡献的去处),因此,我们可以将一个CHAR/BYTE数据和一个整型数据同时作为一个union的成员,得出如下答案:

int checkCPU()

{

 {

  union w

  {

   int a;

   char b;

  } c;

  c.a = 1;

  return (c.b == 1);

 }

}

实现同样的功能,我们来看看Linux操作系统中相关的源代码是怎么做的:

static union { char c[4]; unsigned long l; } endian_test = { { 'l', '?', '?', 'b' } };

#define ENDIANNESS ((char)endian_test.l)

Linux的内核作者们仅仅用一个union变量和一个简单的宏定义就实现了一大段代码同样的功能!由以上一段代码我们可以深刻领会到Linux源代码的精妙之处!

 

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