最近在用串口二进制打包发送数据的时候遇到了大小端的问题,百度了一下随之也出现了LSB,和MSB,自己也是翻了挺多的博客,百科,下面写一下我自己的理解
这些定义需要理解,理解,理解,不能死记,不然后果你们知道的
大端(Big-Endian)
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
有的基础差的同学肯定也想,什么是高地址,什么是低地址,什么是高字节,什么是低字节,我一一来说
高地址和低地址:
这里我们用个例子m=0x12345678, 那么我们unsigned char buf[4]数组来表示吗吧,为什么要用 unsigned char这个类型来定义数组呢,因为 unsigned char这个类型在内存只占一个字节,比较好解释高低字节
在大端中:
地址 | 数据 |
---|---|
buf[0] | 0x12 |
buf[1] | 0x34 |
buf[2] | 0x56 |
buf[3] | 0x78 |
buf[0]到buf[3]地址是从低到高的
这里的0x12,0x34,0x56,0x78都各自表示一个字节,所谓的高字节就是高位的字节,高位就是数据大的意思,那么0x12345678的最高字节就是0x12,最低字节就是0x78
由表可以看出在大端模式中数据的高字节放在了低地址中,低字节放在了高地址中
小端(Little-Endian)
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。
看了大端以后,小端模式正好跟他相反
在小端中:
地址 | 数据 |
---|---|
buf[0] | 0x78 |
buf[1] | 0x56 |
buf[2] | 0x34 |
buf[3] | 0x12 |
可以看出在小端模式中数据的高字节放在了高地址中,低字节放在了低地址中
下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:
若x0=0x11,则是大端; 若x0=0x22,则是小端
#include<stdio.h>
#include<stdlib.h>
int main()
{
short int x;
char x0, x1;
x = 0x1122;
x0 = ((char*)&x)[0]; //低地址单元
x1 = ((char*)&x)[1]; //高地址单元
printf("%x\n",x0);
system("pause");
return 0;
}
这是我在我的电脑上运行的,我的是小端
下面说一下LSB,MSB
首先是名词:
MSB:Most Significant Bit. “最高有效位”
LSB:Least Significant Bit. “最低有效位”
这里说一下MSB和LSB在大小端模式下是不一样的
举个栗子:10011011,那么 1(MSB)001 1011(LSB),MSB是1,LSB是1
看到了吧,有点类似于十进制,如:13265(一万三千二百六十五),其中万位的1就是MSB,个位的5就是LSB。
大端模式:一个多字节数据的高字节在前,低字节在后,以数据 0x1234ABCD 看例子:
低地址 ---------------------> 高地址
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| 12 | 34 | AB | CD |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
那么MSB是0x12在最左侧,LSB是0xCD在最右侧
小端模式:一个多字节数据的低字节在前,高字节在后,仍以 0x1234ABCD 看:
低地址 ---------------------> 高地址
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| CD | AB | 34 | 12 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
那么MSB是0x12在最右侧,LSB是0xCD在最左侧
以上的例子应该比较形象了吧,大家可能会感觉大端模式比较符合人类的习惯啊,存储的顺序和直观理解的顺序是一样的
协议中如果写 “LSB first” ,这就是指数据传输时采用小端模式