大端模式与小端模式

本文最后更新于:2023年2月3日 晚上

大小端模式、MSB和LSB、字节序和比特序

  大小端模式最初出现在通信系统中,也就是约束通信双方必须按照相同的字节顺序来进行通信,否则数据就会出错。那现在讲的机器大小端模式,更多的是指计算机存储系统的大小端。而MSB和LSB通常指硬件传输协议中定义的比特流传输顺序。

大端模式与小端模式的区别

大端模式与小端模式的存储方式

一、大端模式与小端模式(字节序)

  计算机中的内存、硬盘等存储设备,尽管存储系统是16位、32位或64位的,但数据仍然是按照字节为单位来存储的。所以其二进制数据位在内存中存储时有两种存放方式:高字节存放在低地址,所谓大端模式;高字节存放在高地址,所谓小端模式。大端模式和小端是实际的字节顺序和存储的地址顺序对应关系的两种模式。

大端模式:高位字节存放在低地址中,低位字节存放在高地址中。最直观的字节序

使用大端模式的平台:Keil C51

小端模式:高位字节存放在高地址中,低位字节存放在低地址中。最符合人的思维的字节序

使用小端模式的平台:x86、ARM、Keil MDK、DSP

用下图表示更加容易理解。以unsigned int value = 0x12345678为例,分别按照大端模式和小端模式存放在芯片中。记住!!!内存的读写永远从低地址开始读/写。高低位字节以人的阅读习惯定义,从左到右为高位字节到低位字节,例如数字:两千三百七十一(2371),高位是2低位是1。同样的道理去理解字节数据。

低地址 高地址
内存地址 0x00000001 0x00000002 0x00000003 0x00000004
大端模式 0x12(高位字节) 0x34 0x56 0x78(低位字节)
小端模式 0x78(低位字节) 0x56 0x34 0x12(高位字节)

其分辨大小端模式的主要作用是弄清楚字节数据是如何翻译成变量数据的,例如4字节数据转Float数据。

(1)测试大小端

  Union共用体,也叫联合体,在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,以达到节省空间的目的。union变量所占用的内存长度等于最长的成员的内存长度。

  sizeof(union test)的值为4。因为共用体将一个char类型的mark、一个long类型的num变量和一个float类型的score变量存放在同一个地址开始的内存单元中,而char类型和long类型所占的内存字节数是不一样的,但是在union中都是从同一个地址存放的,也就是使用的覆盖技术,这三个变量互相覆盖,而这种使几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构。

1
2
3
4
5
6
7
// 联合体 union
union test
{
char mark;
long num;
float score;
};

C++在线编辑器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

union test
{
char mark[4]; // 4字节
long num; //
float score;
} a;

int main()
{
a.score = 10.0;
printf("high address byte: %x \n",a.mark[3]);
printf("%x \n",a.mark[2]);
printf("%x \n",a.mark[1]);
printf("low address byte: %x \n",a.mark[0]);
printf("%d \n",sizeof(long));

return 0;
}

union中的所有成员起始地址都是一样的,所以&test.mark、&a.num和&a.score的值都是一样的。

  例如在串口传输帧信息时:首先将float数据转化为4字节,然后将数据添加组装至帧信息中,最后发送出去。以浮点数10.0f(0x41200000)为例,首先将其转化为4字节,高地址字节为0x41,低地址字节为0x00,然后将其添加至帧信息中,以低地址先写入的原则按顺序写入0x00,0x00,0x20,0x41,若在小端模式的平台上翻译此4字节数据,则同样要以这样的地址顺序存储data[0]:0x00,data[1]:0x00,data[2]:0x20,data[3]:0x41。

二、LSB与MSB(比特序)

  最高有效位(Most Significant Bit,MSB)指的是一个n位二进制数字中的n-1位,具有最高的权值2^(n-1)。 有时也指Most Significant Byte,指多字节序列中具有最大权重的字节。

  最低有效位(Least Significant Bit,LSB)指的是一个n位二进制数字中的0位,具有最低的权值2^0。有时也指Least Significant Byte,指多字节序列中具有最小权重的字节。

所以0x12345678的最高有效字节就是0x12,最低有效字节就是0x78

(1)高位先行和低位先行

  高位先行即在传输一个字节的时候先传输高位字节MSB;低位先行即在传输一个字节的时候先传输低位LSB。高位先行和低位先行是针对串行数据传输方式来说的。常见的串行传输方式有串口(UART)、I2C、SPI等,其Bit流传输方式是由其传输协议决定,此章节内容与上述的大小端模式切不可混淆,此章所讲是指比特序,而大小端模式讲的是字节序。

串口传输方式是低位先行,芯片在通过TX引脚发送数据时,依次发送位0位1……位7。(UART 通信协议基础

IIC的传输方式是高位先行,MSB 在前,依次发送位7位6……位0。(I2C 通信协议基础