字节序和位序
一、基本概念
1、字节序
字节序是指多字节的数据在内存中的排列顺序,按照排列顺序分为大端字节序和小端字节序。
1.1 大小端字节序
大端字节序:内存的低地址存放数据的高位部分。
小端字节序:内存的低地址存放数据的低位部分。
内存地址空间:CPU的最小寻址空间是字节,内存中每个字节都有唯一的地址编号,在32位的机器上,寻址宽度是32位,寻址空间为(0x00000000~0xFFFFFFFF),地址从0x00000000到0xFFFFFFFF增长;地址小的即为低地址空间,地址大的为高地址。
数据的低位和高位:指的是数据的逻辑位,按照正常的表述方式,靠左边的数据部分是高位,靠右边的数据部分相对低位,如123456。
举例说明:
对于一个占据4个字节的数据0x12345678,假设存储在从0x00000000到0x00000003的内存空间中,按照大端和小端方式存储在内存中的形式如下,
地址空间 | 0x00000000 | 0x00000001 | 0x00000002 | 0x00000003 |
大端存储 | 78 | 56 | 34 | 12 |
小端存储 | 12 | 34 | 56 | 78 |
1.2 网络字节序
为了保证大小端不同的主机之间的网络通信 ,统一规定网络字节序为大端字节序。
注意,网络中发送报文的顺序是从低地址开始发送,按字节依次发送。
如果发送的是一段字节间相互”独立“的数据(如一串由ascii码编码的字符串),发送数据时不需要做大小端转换处理。
那发送什么数据的时候,需要注意大小端呢?发送由多个字节组成的数据时要注意处理字节序,我们比较熟悉的socket通信api中有个struct sockaddr_in结构,当给sin_port成员赋值的时候我们需要用htons函数给端口值做个字节序转换,这个端口值正是一个short类型的数据,占用两个字节的空间。
2、位序
一个字节是由8个比特位构成的,那么在不同的机器上,这8个比特的顺序有差异吗?也是有的。
2.1 大端字节序和小端字节序
一个字节中的比特位也分为高比特位和低比特位,高位比特又叫MSB,低位叫做LSB。注意,高位比特和低位比特是按照比特位在字节中的逻辑位来区分的,比如十进制数字2,二进制码是10,其中MSB是1,LSB是0。
虽然计算机的最小寻址单位是字节,但是字节内的每个比特位空间也是有先后顺序的,尽管这个空间我们无法直接访问,为了方便解释,我们记字节内的比特空间由低到高依次为bit0、bit1、bit2、bit3、bit4、bit5、bit6、bit7。
大端位序:低比特空间存放MSB。
小端位序:低比特空间存放LSB。
大端字节序的主机也是大端位序,小端字节序的主机也是小端位序。
例子:
对于一个二进制数据(MSB)1100 1111(LSB),存放在大端位序和小端位序的内存中,结构如下
比特空间 | bit0 | bit1 | bit2 | bit3 | bit4 | bit5 | bit6 | bit7 |
大端位序 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
小端位序 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
2.2 网络比特序
网络中发送每个字节也是按bit位依次发送的,但是注意,并不是从低比特空间(bit0)到高比特空间(bit7)的顺序发送,而是默认先发送MSB,最后发送LSB。这就要求在小端位序的机器上先发送bit7,而在大端位序的主机上先发送bit0,但这些都由计算机自身处理,和我们没有关系。但是我们在定义位域的时候需要注意了,因为先定义的数据存放在低比特空间,所以在小端机器上LSB要先定义,在大端机器上MSB要先定义,一句话概括就是,定义的位域要符合自身机器的比特序。
二、应用
1、 C语言中的位域
2、 websocket协议头定义
参考博文:一文带你秒懂 字节序(byte order),比特序(bit order),位域(bit field)_byteorder-CSDN博客