一、MSB和LSB

在理解大小端序之前,我们先要理解什么是MSB,什么是LSB

数据在计算机中都是以二进制形式存在的,二进制数的最高为就是MSB,最低位就是LSB

          int
比如以0x23456334为例:

它的二进制:00100011010001010110001100110100
           |                              |
          MSB                            LSB

MSBMost Significant Bit(最高有效位),也就是最高位,最左侧的bit
LSBLeast Significant Bit(最低有效位),也就是最低位,最右侧的bit


二、存储空间的高地址字节 与 低地址字节

除了char外,其它类型的变量空间基本都有很多个字节,比如int的变量空间为4个字节,每个字节都有自己的地址

地址最小的为低地址字节,地址最大的为高地址字节


三、大端序存储和小端序存储

还是以0x23456334为例:

              0x23     0x45     0x63     0x34
它的二进制:00100011 01000101 01100011 00110100
           |                                 |
          MSB                               LSB

大端序存储:MSB所在的字节存储在低地址字节空间,LSB所在字节存储高地址字节空间
小端序存储:相反,MSB所在的字节存储在高地址字节空间,LSB所在字节存储在低地址字节空间

计算机采用哪种端序来存储数据其实都无所谓,都能正确存取数据,
我们程序员并不需要操心,不过我们需要了解这个大小端序这个概念

一般来说,如果Intel或AMD CPU,基本都是小端序的。
ARM、PowerPC CPU则不一定,有些是大端的,有些是小端的。


四、测试计算机的大小端序

我们可以测试自己电脑的大小端序,测试方式有好些种,我们这仅介绍一种即可,溺水三千只需一瓢而饮,
那么多种方法,我们只需要知道一种即可

我们的个人电脑基本都是IntelCpu,不出意外的话应该是小端序的

(1)使用“联合体”来测试

#include <stdio.h>

union un
{
    int a;
    char b;
}test;

int main(void)
{
    test.a = 0x12345678;     //  0x12     0x34     0x56     0x78
    printf("%x\n", test.b);  //?00010010 00110100 01010110 01111000?

    if(test.b == 0x78)
    {
        printf("Little-endain:LSB in low Byte\n");
    }
    else if(test.b == 0x12)
    {
        printf("Big-endain:MSB in low Byte\n");
    }

    return 0;
}

打印结果:Little-endain:LSB in low Byte,为小端序存储

测试原理:
a有四个字节,b只有一个字节,联合体的大小最大成员a的大小,
ab共用联合体空间时,都是从低地址字节空间开始共用空间的

大端序存放时:0x12就应该在低地址字节中,通过b访问以char类型来解释空间时,读到的数据就是0x12
小端序存放时:0x78放在了低地址字节中,通过b访问以char类型来解释空间时,读到的数据就是0x78


五、通信中的大小端序

通信时与存储无关,只与数据的传输有关,我们这里说的通信默认指都是串行通信,
因为只有串行通信才存在“通信大小端”的问题

我们还是以0x23456334为例:

              0x23     0x45     0x63     0x34
它的二进制:00100011 01000101 01100011 00110100
           |                                 |
          MSB                               LSB

(1)通信大端序
串行传输时,如果先从MSB开始发送,这就是通信的大端序,
通信大端序由于是MSB先被发送,因此也被称为MSB先行

(2)通信小端序
串行传输时,如果先从LSB开始发送,这就是通信的小端序,
通信小端序由于是LSB先被发送,因此也被称为LSB先行

我们在学习单片机/嵌入式的SPII2CUSB、网络通信时,
底层硬件在收发数据时就会涉及到MSB先行和LSB先行的问题,所以了解通信大小端序是有意义的