那谁的技术博客

感兴趣领域:高性能服务器编程,存储,算法,Linux内核
随笔 - 210, 文章 - 0, 评论 - 1183, 引用 - 0
数据加载中……

little endian和big endian的概念解释,判定与用途


       little endian和big endian是表示计算机字节顺序的两种格式,所谓的字节顺序指的是长度跨越多个字节的数据的存放形式.
        假设从地址0x00000000开始的一个字中保存有数据0x1234abcd,那么在两种不同的内存顺序的机器上从字节的角度去看的话分别表示为:
       1)little endian:在内存中的顺序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12
       2)big  endian:在内存中的顺序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd
       需要特别说明的是,以上假设机器是每个内存单元以8位即一个字节为单位的.
       简单的说,little endian把低位存放到高位,而big endian把低位存放到低位.
       现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian.
      
       以下是判断字节存储顺序的可移植的C语言代码:
      

/* *******************************************************************
    created:    2006-9-5
    filename:     test.cpp
    author:        李创
    
    purpose:    可移植的用于判断存储格式是
                little endian还是big ednian的C代码
                取自<<C: A Reference Manual>>
********************************************************************
*/


#include 
< stdio.h >

union
{
    
long  Long;
    
char  Char[ sizeof ( long )];
}
u;

int  main()
{    
    u.Long 
=   1 ;
    
    
if  (u.Char[ 0 ==   1 )    
    
{
        printf(
" Little Endian!\n " );
    }

    
else   if  (u.Char[ sizeof ( long -   1 ==   1 )
    
{
        printf(
" Big Endian!\n " );
    }

    
else
    
{
        printf(
" Unknown Addressing!\n " );
    }


    printf(
" Now, Let's look at every byte in the memory!\n " );
    
for  ( int  i  =   0 ; i  <   sizeof ( long );  ++ i)
    
{
        printf(
" [%x] = %x\n " & u.Char[i], u.Char[i]);
    }


    
return   0 ;
}

 

       很多人认为掌握这个知识是不必要,其实不然.在网络编程中,TCP/IP统一采用big endian方式传送数据,也就是说,假设现在是在一个字节顺序是little endian的机器上传送数据,要求传送的数据是0XCEFABOBO,那么你就要以0XBOBOFACE的顺序在unsigned int中存放这个数据,只有这样才能保证存放的顺序满足TCP/IP的字节顺序要求.很多时候,需要自己编写应用层的协议,字节顺序的概念在这个时候就显得及其的重要了.
       下面给出的是在big endian和little endian中相互转换的代码,C语言强大的位操作的能力在这里显示了出来:
        

/* *******************************************************************
    created:    2006-9-5
    filename:     get32put32.cpp
    author:        李创
    
    purpose:    在little endian和big ednian之间相互转化数据的演示代码

********************************************************************
*/



#include 
< stdio.h >

const  unsigned  char  SIZE_OF_UNSIGNEDINT   =   sizeof (unsigned  int );
const  unsigned  char  SIZE_OF_UNSIGNEDCHAR  =   sizeof (unsigned  char );

void  put_32(unsigned  char   * cmd, unsigned  int  data)
{
    
int  i;
    
for  (i  =  SIZE_OF_UNSIGNEDINT  -   1 ; i  >=   0 -- i)
    
{
        cmd[i] 
=  data  %   256 ;
        
//  或者可以:
        
// cmd[i] = data & 0xFF;
        data  =  data  >>   8 ;
    }

}


unsigned 
int  get_32(unsigned  char   * cmd)
{
    unsigned 
int   ret;
    
int  i;

    
for  (ret  =   0 , i  =  SIZE_OF_UNSIGNEDINT  -   1 ; i  >=   0 -- i)
    
{
        ret  
=  ret  <<   8 ;
        ret 
|=  cmd[i];        
    }

    
    
return  ret;
}


int  main( void )
{
    unsigned 
char  cmd[SIZE_OF_UNSIGNEDINT];
    unsigned 
int  data, ret;
    unsigned 
char   * p;
    
int  i;

    data 
=   0x12345678 ;
    printf(
" data = %x\n " , data);
    
//  以字节为单位打印出数据
    p  =  (unsigned  char * )( & data);
    
for  (i  =   0 ; i  <  SIZE_OF_UNSIGNEDINT;  ++ i)
    
{
        printf(
" %x " * p ++ );
    }

    printf(
" \n " );

    
//  以相反的顺序存放到cmd之中
    put_32(cmd, data);
    
for  (i  =   0 ; i  <  SIZE_OF_UNSIGNEDINT;  ++ i)
    
{
        printf(
" cmd[%d] = %x\n " , i, cmd[i]);
    }


    
//  再以相反的顺序保存数据到ret中
    
//  保存之后的ret数值应该与data相同
    ret  =  get_32(cmd);
    printf(
" ret = %x\n " , ret);
    p 
=  (unsigned  char * )( & ret);
    
for  (i  =   0 ; i  <  SIZE_OF_UNSIGNEDINT;  ++ i)
    
{
        printf(
" %x " * p ++ );
    }

    printf(
" \n " );

    
return   0 ;
}





参考资料:<<C: A Reference Manual>>

posted on 2006-09-05 21:04 那谁 阅读(2250) 评论(4)  编辑 收藏 引用 所属分类: C\C++

评论

# re: little endian和big endian的概念解释,判定与用途  回复  更多评论   

bu cuo
2006-09-06 10:07 | 一秋草木

# re: little endian和big endian的概念解释,判定与用途  回复  更多评论   

tcp/ip并没有规定要用什么方式传数据
2006-09-07 09:21 | qinglan

# re: little endian和big endian的概念解释,判定与用途  回复  更多评论   

"简单的说,little endian把低位存放到高位,而big endian把低位存放到低位."
这句话应这么说吧

big endian把低位存放到高位,而little endian把低位存放到低位.
2007-12-06 16:27 | bitop

# re: little endian和big endian的概念解释,判定与用途  回复  更多评论   

"big endian把低位存放到高位,而little endian把低位存放到低位."
这样说才对啊
2009-03-25 16:45 | skyline

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理