大小端
来源:互联网 发布:用淘宝可以贷款吗 编辑:程序博客网 时间:2024/04/29 08:08
一、字节序
对一个主机系统来说,存储的空间总是有高位和低位的,那么对于一个数据来说,数据的高位和地位与存储空间的高位和低位如何对应,这就是字节序的问题。
字节序有两种:大端(big-endian)和小端(little-endian)。简单描述如下
大端:数据的高位对应存储空间的低位,数据的低位对应存储空间的高位
小端:数据的高位对应存储空间的高位,数据的低位对应存储空间的低位
举例:
一个2字节的数HByte,LByte。那么存储的情况如下
对于大端来说,存储结构如下
+——–+ 高位
| LByte |
+——–+
| HByte |
+——–+ 低位
假设有个数a=0×12345678,那么实际的存储顺序就是
|12|34|56|78|
低位 高位
也就是说,如果要在网络上发送的话,先发送的就是12
对于小端,刚好反过来,存储结构如下
+——–+ 高位
| HByte |
+——–+
| LByte |
+——–+ 低位
对于数0×12345678来说,存储顺序就是
|78|56|34|12|
低位 高位
如果要在网络上发送,就先发送78
如果将一个32位的整数0x12345678 存放到一个整型变量(int)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。为简单 起见,本文使用OP0表示一个32位数据的最高字节MSB(Most Significant Byte),使用OP3表示一个32位数据最低字节LSB(Least Significant Byte)。
地址偏移
大端模式
小端模式
0x00
12(OP0)
78(OP3)
0x01
34(OP1)
56(OP2)
0x02
56(OP2)
34(OP1)
0x03
78(OP3)
12(OP0)
如果将一个16位的整数0x1234存放到一个短整型变量(short)中。这个短整型变量在内存中的存储在大小端模式由下表所示。
地址偏移
大端模式
小端模式
0x00
12(OP0)
34(OP1)
0x01
34(OP1)
12(OP0)
大端:高位存在低地址,低位存在高地址。
小端:高位存在高地址,低位存在低地址。 (intel的x86,ARM普遍都是属于小端)。
二、网络序和主机序
就如同上面的例子中说的那样,同一个数据,对于大端和小端两种系统,向网络上发送数据的顺序是不同的,这样就可能出现问题。
比如一个大端的系统发送了0×12345678这个数据,那么发送的顺序是先发12,最后发送78。收到的时候也是先收到12,最后收到78。如果接收的系统也是大端的没有问题,但如果接收系统是小端的,那么该数据就可能被解析成0×78563412,因为小端系统认为先发送的字节应该是最低的字节。 这就出问题了。所以必须有一个规范,这就是主机序和网络序的概念。
网络序规定是大端序的。主机序则根据主机来决定。
按照规定,在网络上发送的数据都必须是网络序的,主机上的数据如果需要发送到网络上都应该先转成网络序。收到数据后,在转成本机的主机序。这样就不会出问题了。
主机序和网络序的转换有一些宏,比如:hton ntoh,htons ntohs,htonl ntohl
还是上面那个0×12345678为例
大端序的系统发送的时候,将消息转成网络序,发送,也就是12 34 56 78这个顺序
小端系统收到的时候,将网络序的消息,转成主机序,也就是将大端序的消息转成小端序。这样,在内存中本来应该是 +低位|12|34|56|78|高位+这样存放次序的消息,就转成了+低位|78|56|34|12|高位+,也就是在小端序下能正确解析成0×12345678了。
三、位序
也就是位域中的顺序问题
比如
struct bitfield
{
char a1:1;
char a2:1;
char a3:1;
char a4:1;
char a5:1;
char a6:1;
char a7:1;
char a8:1;
};
做如下赋值
struct bitfield testbit;
memset(&testbit;,0,sizeof(struct bitfield));
testbit.a8 = 1
那么输出的testbit的结果会是多少呢?
大端序系统中,输出结果为1,小端系统中输出结果为-128。为什么会是这个结果呢,分析如下
1.ANSI-C要求在struct里面,先声明的成员占有低地址。不管是大端还是小端系统都是这个要求。
根据这个要求,a8就是处于高位得。假设左边是高地址,责这个赋值后,testbit得值如下
1000 0000
2.小端系统(比如IA32)中,高位在高地址,低位在低地址,这样a8=1就是表示最高位为1,所以这个值就是-128了
3.大端系统中,高位在低地址,低位在高地址,也就是a8=1表示得是最低位,一个字节得最低位为1,其位为0,最后得值自然也就是1了。