一、字节序 对一个主机系统来说,存储的空间总是有高位和低位的,那么对于一个数据来说,数据的高位和地位与存储空间的高位和低位如何对应,这就是字节序的问题。 字节序有两种:大端(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)。
如果将一个16位的整数0x1234存放到一个短整型变量(short)中。这个短整型变量在内存中的存储在大小端模式由下表所示。
大端:高位存在低地址,低位存在高地址。
小端:高位存在高地址,低位存在低地址。 (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了。 |
大小端
最新推荐文章于 2024-05-29 19:10:43 发布