Chinaunix首页 | 论坛 | 博客
  • 博客访问: 169961
  • 博文数量: 13
  • 博客积分: 2123
  • 博客等级: 大尉
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-05 20:25
文章分类

全部博文(13)

文章存档

2011年(1)

2010年(4)

2009年(5)

2008年(3)

我的朋友

分类:

2011-02-11 13:31:47

Big endian Little endian区别的解析

Linux,C语言和多核编程 2010-09-17 15:51:08 阅读56 评论0   字号: 订阅

嵌入式编程的面试或被面试的过程中,经常会有Little EndianBig Endian相关的面试问题,分析区别或者写程序来判断一个CPULittle Endian还是Big Endian 这里做一下总结。

一、Big EndianLittle Endian的概念

计算机的所有内存以字节数组的方式进行编址。

当一个逻辑上长于一个字节的整形数据放置在内存中时(比如16位,32位,和64位的整数),需要考虑这些字节的存储顺序。Little Endian: 将字节的逻辑顺序与物理顺序一致,即将逻辑上较低的字节放置在物理上较低的字节上,比如Intel x86系列;

Big Endian字节的逻辑顺序与物理顺序相反,即将逻辑上较低的字节放置在物理上较高的字节上,比如MotorolaPowerPC以及Sun Sparc。还有一些平台同时支持两种方案,由开发者决定使用哪一种。

例如数字0x89ABCDEF,有四个字节组成,分别为0x89, 0xAB, 0xCD, 0xEF, 相应的算术值为0x890000000xAB0000, 0xCD000xEF,很明显,0x89的值最大,称之为数字0x89ABCDEF的最高位,而0xEF为最低位。数字在内存中的存放,从低位起,有两种存放方式,分别为:

1 先存放最低位(little endian

2 先存放最高位(big endian

下图表明不同的处理器是如何在内存中,按照big endianlittle endian存放32位十六进制数的,如0x89ABCDEF

 各自的优势:由于Little Endian提供了逻辑顺序与物理顺序的一致性,让编程者摆脱了不一致性所带来的困扰,C语言开发者可以无所顾忌的按照自己的意愿进行强制类型转换;但Big Endian也有其优点,尤其对于汇编程序员:他们对于任意长度的整数,总是可以通过判断Byte 0bit-7来查看一个整数的正负(补码的首位标识正负);对于Little Endian则不得不首先知道当前整数的长度,然后查看最高bytebit-7来判断其正负。对于这种情况,big endian的开发者可以写出非常高效的代码。

TCP/IP协议指定其数据格式为Big endian,因此Big EndianCPU处理起来更方面;对于Little-EndianCPU, x86,应用中需要首先转换TCP/IP的数据为little endian格式。实际上,POSIX提供相应的操作函数,这些函数是htonl(), ntohl(), htons()ntohs()

需要特别指出的是,通常所提到的Little EndianBig Endian仅仅指字节顺序.

二、如何通过程序来判断CPUBig Endian还是Little Endian

1. 利用union来判断

联合中的数据成员是共享存储空间的,所分配的空间为数据成员中最大所需的内存数。union 的成员本身就被存放在相同的内存空间(共享内存,正是union 发挥作用的地方),因此,可以将一个字节型数据和一个整型数据同时作为一个union 的成员,通过如下的代码来测试endian的模式。

#include "stdio.h"

typedef union endian_test{
        int a;
        char b;

} e_t;

int main()

{
        e_t c;
        c.a = 1;

        if  (c.b)
                printf("little endian\n");
        else
                printf("big endian\n");

        return (int)c.b;

}

分析:union e_t 由四个字节构成。其分布如下表:

Uninon

Byte0

Byte1

Byte2

Byte3

a

b

 

 

 

Big Endian

0

0

0

1

Little Endian

1

0

0

0

int a 将占用4个字节,char b占用一个字节(Byte 0)。如果将a赋值为1,那么在Big Endian模式下,它将处于Byte 3的位置,所以此时取到的联合体中b的值为0;在Little Endian模式下,1将处于Byte 0的位置,所以b的值将为1.

2. 通过强制类型转换来判断

将一个字节(CHAR/BYTE 类型)的数据和一个整型数据存放于同样的内存开始地址,通过读取整型数据,分析CHAR/BYTE 数据在整型数据的高位还是低位来判断CPU 工作于Littleendian 还是Big endian 模式。

#include "stdio.h"
int main(int argc, char* argv[])
{

 unsigned int num = 0;

 unsigned int *p;

 p = #

 *(unsigned char *)p = 0x1; // Set BYTE0 to 0X1

 if (num == 1)

 {

    printf("little endian\n");

 }

 else // num == 0x1000000

 {

     printf("big endian\n");

 }

 return 0;
}
This is the layout of memory:

num

Byte0

Byte1

Byte2

Byte3

 

char *

 

 

 

 

int *

 

Big Endian

1

0

0

0

0x1000000

Little Endian

1

0

0

0

0x1

参考文献:

http://shitou118.blog.51cto.com/715507/349895

http://blog.myspace.cn/e/401643257.htm

 

阅读(1611) | 评论(0) | 转发(0) |
0

上一篇:H264 视频文件 帧格式 传输封装等

下一篇:没有了

给主人留下些什么吧!~~