大端模式和小端模式的定义:
大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中;
小端模式(Little_endian):字数据的低字节存储在低地址中,而字数据的高字节则存放在高地址中;
为什么会有大小端模式之分呢?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit 。但是在 C 语言中除了 8bit 的 char 之外,还有 16bit 的 short 型, 32bit 的 long 型(要看具体的编译器),另外,对于位数大于 8 位的处理器,例如 16 位或者 32 位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小 端存储模式。例如一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为高字节, 0x22 为低字节。对于 大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模 式,而 KEIL C51 则为大端模式。很多的 ARM , DSP 都为小端模式。
如何确定大小端?
可以利用union类型数据
int check()
{
union check
{
int i;
char ch;
}c;
c.i=1;
return (c.ch==1)
}
显然,返回1则为小端,返回0则为大端。
一个更难一些的问题:
在x86系统下,以下程序的运行结果为多少?
int main(int argc,char* argv[])
{
int a[4]={1,2,3,4};
int *p1=(int *)(&a+1);
int *p2=(int *)((int)a+1);
printf("%x,%x/n",p1[-1],*p2);
return 0;
}
结果为4,0x2000000
第一个值很好理解,只要知道(int *)(&a+1)为a[5]的地址就可以了
第二个值的解释见下图:
--------------------------------------->高地址
0x01 0x00 0x00 0x00 0x02 0x00 0x00 0x00
以上为小端模式下(题目指明x86)a[0]、a[1]的存储模式
int *p2=(int *)((int)a+1);后,*p2应为a[0]的第二个字节开始的连续4个byte的内容,
,即0x00 0x00 0x00 0x02,从内存中读取这4个字节,则读为0x2000000