为什么会关心大小端问题 ?
在控制系统中,由于CPU架构以及编译器等因素决定了数据的存储方式,不同的存储方式,其数据的发送/解读方式需要使用响应的方法。
因此,在数据传输时,我们有必要弄清楚两台或多台设备的存储方式是大端还是小端。尤其是在两台存储方式不同的设备之间实现通信,必须要搞明白这件事情,否则可能会导致数据解读不正确的问题。
大小端的起源不在进行赘述,请参考维基百科等文献。
大端(Big-Endian): 低地址存放高位
小端(Little-Endian): 低地址存放低位
举个栗子,对于0x12345678这个数,存放在地址0x4000中,大小端的存储方式区别如下表:
内存地址 | 小端模式存放内容 | 大端模式存放内容 |
---|---|---|
0x4000 | 0x78 | 0x12 |
0x4001 | 0x56 | 0x34 |
0x4002 | 0x34 | 0x56 |
0x4003 | 0x12 | 0x78 |
再来个更直观的叙述方式:
对于大端模式:
对于小端模式:
大端存储:顺序存储,符合人的思维,符号位的判定固定为第一个字节,容易判断正负;
小端存储:强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。
另外,对于大小端的处理也和编译器的实现有关:
此外,
对于这个问题,百度百科也给出了一些测试程序1。
测试方法由多种:
#include
int check_sys()
{
union UN
{
char c;
int i;
}un;
un.i = 1;
if (un.c == 1)
{
return 0;
}
else
{
return 1;
}
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("Is big endian\n");
}
else
{
printf("Is little endian\n");
}
return 0;
}
#include
int check_sys()
{
int i = 1;
int *p = &i;
char *q = (char *)p;
if (*q == 1)
{
return 0;
}
else
{
return 1;
}
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("Is big endian\n");
}
else
{
printf("Is little endian\n");
}
return 0;
}
思路1:直接交换字节
思路2:先与再移位,得到各地址的数据,最后按相应的顺序排列
(( a&0x000000ff)<< 24 ) | ( ( a&0x0000ff00 ) << 8 ) | ( ( a&0x00ff0000 ) >> 8 ) | ( ( a&0xff000000 ) >> 24 )
具体代码参见其他博文。
https://baike.baidu.com/item/%E5%A4%A7%E5%B0%8F%E7%AB%AF%E6%A8%A1%E5%BC%8F/6750542?fr=aladdin ↩︎ ↩︎