大端模式和小端模式

对于整型和长整型等数据类型,big endian 认为第一个字节在高位字节(按照地址从低到高的顺序存放数据的高位字节和低位字节),而little endian则相反,认为第一个字节是最低位字节(按照从低地址到高地址的顺序存放数据的地位字节和高位字节)。

例如:假设从内存地址0x0000开始有以下数据:

0x0000     0x0001    0x0002     0x0003     

0x12   0x34   0xab     0xcd

如果我们去读取一个地址为0x0000四字节的变量,若字节序为big-endian,则读出的结果为   0x1234abcd   若字节序为little-endian,则读出的结果为0xcdab3412

如果我们将0x1234abcd写入到以0x0000开始的内存中,则little-endian和big-endian模式的存放结果如下地址

地址:      0x0000    0x0001     0x0002       0x0003

big-endian      0x12   0x34   0xab    0xcd

little-endian   0xcd    0xab   0x34    0x12

一般来说,x86系列cpc都是低字节序的,powerpc通常是big-endian还有的cpu能通过跳线来调节cpu是工作于little-endian还是big-endian模式

对于0x12345678的存储:

小端模式(从低字节到高字节)低位地址0x78 0x56 0x34 0x12  高位地址

大端模式(从高字节到低字节)低位地址0x12 0x34 0x56 0x78  高位地址

  main(){

    char  *sz; =“0123456789”;

    int *p= (int *)sz;

    printf("%x\n",*++p);

  }

字符0对应的十六进制是0x30,请问程序输出是多少?

只要考察的目的是大端问题和小端问题

对于intel的cpu是小端模式,如果出现跨多个自己的数据类型,如int,long等,低地址存储数据的低位,高地址存储数据的高位

地址从@0开始,那么sz在内存的存储为

@0         @1       @2       @3  @4     @5      @6      @7      @8       @9

0x30     0x31    0x32     0x33   0x34  0x35    0x36    0x37   0x38    0x39

当你把char *强制转换成int * 后,因为int 占四个字节,那么p指向@0,并且*p占用的内存是@0@1@2@3打印的时候先执行++p操作,那么p指向@4,此时*p占有的地址

为@4@5@6@7,根据上面的低地址存低位,高地址存高位的解释,那么*p应该等于0x370x360x350x34

int a=0x12345678

char *p = (int *)&a;

printf("%x\n",*(p+1));

例如对于0x12345678,大部分unix机器和网络是这样0x12 0x34 0x56 0x78,这种方式成为big-endian

题目中的p指向0x78 加1 后指向0x56

二、大端小端转换方法

big-endian 转换为little-endian

#define bigtolittle16(A)   ((((uint16(A) & 0xff00)>>8|(((uint16(A)&0x00ff)<<8))

#define bigtolittle32(a)    ((((uint32(A)&0xff000000)>>24 |\

             (((uint32(A)&0x00ff0000)>>8 |\

             (((uint32(A)&0x0000ff00)<<8 |\

             (((uint32(A)&0x000000ff)<<24 ))

三、大端小端判断
  如何检测处理器是big-endian还是little-endian

#include "stdio.h"

 int main(){    

      int i = 1; 

      char *p = ( char *)&i;

        if( *p == 1){      

       printf("little endian\n");
        }else{ 

           printf("big endian\n");
    }

}

大小端存储问题,如果小端方式中(i 占至少两个字节的长度),则i所分配的内存最小地址那个字节中就存着1,其他字节是0,大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端。
posted @ 2011-05-17 17:32  jerryking  阅读(718)  评论(0编辑  收藏  举报