大端和小端

来源:互联网 发布:cad迷你看图软件 编辑:程序博客网 时间:2024/06/09 20:19

基本概念

我们可以把计算机的内存抽像成一个大的数组,在这个数组中,包含了一个个的字节元素。对于大小端的讨论,我们可以认为内存的最小单元即是一个字节(byte)。对于每个字节,我们可以使用一个“索引”来标识,这个索引亦即我们平常所说的内存的地址。
假定计算机的字长为32位,即一个字包括4个字节。对于一个32位整数,例如,0x90AB12CD。由于每个十六进制的数字代表了4个位(bits),故我们需要8个十六进制数字来表示这个32位整数。即这个32位整数的四个字节分别为
90, AB,12,CD
根据存储这4个字节顺序的不同,可以分为大端存储和小端存储。

大端(Big Endian)

如果一个数据的高字节保存在内存的低地址处,数据的低字节保存在内存的高地址处,则这种存存储方式称为大端存储模式。
例如,对于0x90AB12CD存储在内存地址为1000开头的四个字节处,如果使用大端存储,则其内存布局如下图所示:
大端存储

小端(Little Endian)

如果一个数据的高字节保存在内存的高地址处,数据的低字节保存在内存的低地址处,则这种存存储方式称为小端存储模式。
例如,对于0x90AB12CD存储在内存地址为1000开头的四个字节处,如果使用小端存储,则其内存布局如下图所示:
小端存储

Endian名称的历史由来

Jonathan Swift在其讽刺小说Gulliver’s Travels(《格利佛游记》)描述了以下情景。在一个小人国,对如何吃水煮蛋存在分歧,有的认为先从小的一端剥开,有的认为先从大的一端剥开,因此形成了两派,支持从大端剥开的称为(Big Endian),支持从小端剥开的称为(Little Endian),并引发了一场战争。
这是endian一词的最早由来。

误区

大小端仅在一个数的存储结构可以被切分为多个不同的存储单元时才有意义,这时,我们必须确定存储的顺序。
对于一个32位的寄存器来说,要保存一个32位的数值,在这种情况下,没有大小端的概念。这个寄存器的最右端位保存这个数的低位,最左端位保存数的高位。
同样的,对于一个C风格的字符串(C-style string,以’\0’结尾的字符串)来说,也不存在大小端的概念。C-style string可以看成字符数组,数组的每个元素为一个存储了单个字符的字节。对于数组来说,内存地址总是递增的。例如&arr[i]的值小于&arr[i+1]的值。这样,C-style string字符的地址也是从左往右依次递增。
故C-style string不存在需要确定字符存储顺序的问题,也即不存在大小端的概念。

程序判断大小端模式

int main(){    unsigned int i = 1;    char *p = (char*)&i;    if (*p)        cout << "little" << endl;    else        cout << "big" << endl;    return 0;}

变量i为非负整型,占四个字节(32位),其值为0x00000001,即
00,00,00,01
为了确定低位的1存储在内存地址的低位还是内存地址高位,我们使用char*型指针p指向i的第一个字节,通过判断*p的值,即可以确定机器是大端还是小端。如果低位的1存储在内存地址的低位,即*p不为0,说明为小端模式;如果低位的1存储在内存地址的高位,即*p为0,说明为大端模式。

参考资料

  1. Big and Little Endian
  2. 大小端模式,百度百科
  3. Endian,百度百科
0 0
原创粉丝点击