【词条】大端(big-endian)模式和小端(little-endian)模式

来源:互联网 发布:前端js比较炫酷的网站 编辑:程序博客网 时间:2024/05/16 01:04

1、我们知道当定义一个变量的时候,操作系统会为这个变量分配一段内存,具体分配哪段内存由操作系统的内存分配策略决定。

例如short int x = 0x1234;(为了好理解,我们这里使用16进制表示)

这个时候操作系统会为x分配两个字节的内存(假设为0x4000、0x4001这两个地址)

(1)如果x在内存中按照下面的方式存储

内存地址

0x4000

0x4001

存放内容

0x12

0x34

那么它就是大端(big-endian)模式。
(2)如果x在内存中按照下面的方式存储

内存地址

0x4000

0x4001

存放内容

0x34

0x12

那么它就是小端(little-endian)模式。
可见,大端模式是符合我们人类思维习惯的。
 
总结:所谓big-endian是指低位内存地址存放最低有效字节(LSB);big-endian是指低位内存地址存放最高有效字节(MSB)。
 
2、大端模式、小端模式是由什么决定的呢?
答:谈到字节序的问题,必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。
      C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而 JAVA编写的程序则唯一采用big endian方式来存储数据。可见,大端模式、小端模式是有处理器(CPU)决定的,而编译器在生成程序的时候,又可能会改变这种模式。
 
3、什么是网络字节序?
答:所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。
 
4、再来谈点深入的,大端、小端模式实际上是CPU在存储不同字节的数据时的顺序问题,那么CPU在存储一个字节的数据时其字节内的8个比特之间的顺序是否也有littele-endian和big-endian只分呢,或者说比特序是否有不同?
答:实际上,这个比特序是同样存在的。下面以数字0xB4(10110100)用图加以说明。
                  Big Endian
                              msb                                                        lsb
                            ---------------------------------------------->
                             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                               | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
                             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                  Little Endian
                             lsb                                                            msb
                             ---------------------------------------------->
                            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 |
                            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           实际上,由于CPU存储数据操作的最小单位是一个字节,其内部的比特序是什么样对我们的程序来说是一个黑盒子。也就是说,你给我一个指向0xB4这个数的指针,对于big endian方式的CPU来说,它是从左往右依次读取这个数的8个比特;而对于little endian方式的CPU来说,则正好相反,是从右往左依次读取这个数的8个比特。而我们的程序通过这个指针访问后得到的数就是0xB4,字节内部的比特序对于程序来说是不可见的。
 
5、如何确定CPU的字节序是大端模式还是小端模式呢?
答:
         short int i = 0x1234;char x = 0x12;char y = 0x34;char c = *(char *)&i;//低位地址存放的是最高有效字节if (x == c){cout << "big endian" << endl;}//低位地址存放的是最低有效字节if (y==c){cout << "little endian" << endl;}
还有一个程序相当有趣,可以用来判断大小模式,它用到了联合体的特性
int main(){union{short int i;char c;}u;u.i = 1;if (u.c == 1){cout << "little endian" << endl;}if (u.c == 0){cout << "big endian" << endl;}

还有一个联合体的程序,也很有趣
int main(){union{long l;char c[sizeof(long)];}u;u.l = 1;if(u.c[sizeof(long)-1] == 1){cout << "big endidan" << endl;}if (u.c[0] == 1){cout << "little endian" << endl;}}

 
原创粉丝点击