大小端

来源:互联网 发布:用淘宝可以贷款吗 编辑:程序博客网 时间: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了。

原创粉丝点击