题目:如何判断一个机器是大端还是小端

来源:互联网 发布:js获取系统当前日期 编辑:程序博客网 时间:2024/04/19 10:47

如何判断一个机器是大端还是小端 

    关于大端小端的概念,

    小端:数据的高位字节存放在高地址内,数据的低位字节存放在低地址内。

    大端:数据的高位字节存放在低地址内,数据的低位字节存放在高地址内。

    典型的体系结构中,一个字是4个字节,那么数据0x0A0B0C0D,在小端机器中从地址到高址的存放方式为:0x0D,0x0C,0x0B,0x0A;

   在大端模式中从地址到高地址的存放方式为:0x0A,0xB,0x0C,0x0D;

   通用处理器中,ARM通常是大端模式,x86体系机构是小端模式。

   如果让你判断一个处理器的类型,你该如何编码实现呢,如果是用汇编语言,那这是一件非常容易的事情,向指定地址写一个数据,

   再逐个字节的读出来,就能很容易判断出大小端。那么用C语言如何实现呢?  

    方法一、通过读取同一地址的整型数据和字符数据来区别大端和小端    

复制代码
 1  unsigned int data,* point; 2     point=&data;//获取整型数据的地址,保存在point中 3     data=0; 4     *(type *) point= 0x22; 5     if(data==0x22) 6     { 7         cout<< "此处理器是小端!"<<endl; 8     } 9     else  if(data==0x22000000)10     {11         cout<< "此处理器是大端!"<<endl;12     }13     else14     {15         cout<< "暂时无法判断机器类型!"<<endl;16     }
复制代码

 

 

    方法二、通过union的共享内存特性,来判断机器类型    

复制代码
 1  union 2     { 3         char str; 4         int data; 5     }; 6     data=0x01020304; 7     if(str==0x01) 8     { 9         cout<< "此机器是大端!"<<endl;10     }11     else if(str==0x04){12         cout<<"此机器是小端!"<<endl;13     }14     else{15         cout <<" 暂无法判断此机器类型!"<<endl;16     }
复制代码

 方法三、Linux的开发者,在内核中只用这样两句话,就判断了机器类型

1  static union { char c[4]; unsigned long mylong; } endian_test = {{ 'l', '?', '?', 'b' } };2     #define ENDIANNESS ((char)endian_test.mylong)3     cout<<ENDIANNESS<<endl;
联合体(union)数据类型的特性吧-----成员变量c和i公用一段内存,当系统我32位系统时,正好,unsigned long类型占4个字节,char为一个字节
我们假设从左到右内存地址依次增高,那么'l', '?', '?', 'b' 这四个字符在不同的系统将会这样放置:
'l', '?', '?', 'b'  ------ 小端(little-endian)系统(低低模式,即低字节放在低地址)
'b','?', '?', 'l'   ------ 大端(big-endian)系统(高低模式,即高字节放在低地址)
那么宏中的这条语句((char)endian_test.l)很明显是取long变量的第一个字节,那么如果返回‘l’,说明是小端,如果返回 'b'。说明是大端。
在从l到char的强制转换时,取的是“低字节”,而低字节在哪里呢?这就要看大端小端了。如果是大端,低字节就是b,反之为l。
所以最后一句应该改为“不论大端小端,都截取低字节,而低字节是谁,由大端小端决定。”
方法四、

bool CheckBig()

{

int i=1;    // i 在的二进制就是 00000001 在内存中占 4个字节 

char *p=(char *)&i;   //将 i 地址传给 p 并强制转换成char 类型,为的是造成 *p和i 所占字节数不同,因为可以判断 *p的数据损失情况

return (*p==1);// 若是大端,则*p留下的就是00000001 的 低位(即01),若是小端则留下的是00000001的高位(即 00)

//因而 true为大端 false 为小端

}

0 0