计算机存储系统——大小端模式

  • Post author:
  • Post category:其他




大小端模式介绍

在计算机内存/硬盘/Nnad中。因为存储系统是32位的,但是数据仍然是按照字节为单位的。

于是乎一个32位的二进制在内存中存储时有2种分布方式:

高字节对应高地址(小端模式)//常见arm、x86、DSP

高字节对应低地址(大端模式)//keil5

解析:
0x12345678,其中12相对34相对56相对78为高字节
0x00000001相对0x00000000为高地址



判断机器大小端的两种方式:

第一种:共用体

union myunion 
{
	int a;
	char b;
};
void little_endian(void)
{
	union myunion u1;
	int ret = 0;
	
	u1.a = 1;
	if(u1.b ==1){
		printf("小端模式\n");
	}else{
		printf("大端模式\n");
	}
} 
int main()
{
	
	little_endian();
	
	return 0;
}

第二种:指针方式来测试机器的大小端

#include <stdio.h>

union myunion 
{
	int a;
	char b;
};

void little_endian2()
{
	int a = 1;
	char b;
	b = *((char*)(&a));
	
	if(b ==1){
		printf("小端模式\n");
	}else{
		printf("大端模式\n");
	}
	
}
int main()
{
	
	little_endian2();
	
	return 0;
}



不可以用于判断大小端的三种方式:

1.位与运算:

位与运算是编译器提供的运算,这个运算是高于内存层次的(或者说&运算在二进制层次具有可移植性,也就是说&的时候一定是高字节&高字节,低字节&低字节,和二进制存储无关)。

	// 位与
	int a = 1;
	int b = a & 0xff;		// 也可以写成:char b = a & 0x01;
	printf("b = %d.\n", b);

2.移位运算:

原因和&运算符不能测试一样,因为C语言对运算符的级别是高于二进制层次的。右移运算永远是将低字节移除,而和二进制存储时这个低字节在高位还是低位无关的。


	int a, b;
	a = 1;
	b = a >> 1;
	printf("b = %d.\n", b);

3.强制类型转换

	// 强制类型转换
	int a;
	char b;
	a = 1;
	b = (char)a;
	printf("b = %d.\n", b);



通信系统种的大小端模式

(1)譬如要通过串口发送一个0x12345678给接收方,但是因为串口本身限制,只能以字节为单位来发送,所以需要发4次;接收方分4次接收,内容分别是:0x12、0x34、0x56、0x78.接收方接收到这4个字节之后需要去重组得到0x12345678(而不是得到0x78563412).

(2)所以在通信双方需要有一个默契,就是:先发/先接的是高位还是低位?这就是通信中的大小端问题。

(3)一般来说是:先发低字节叫小端;先发高字节就叫大端。实际操作中,在通信协议里面会去定义大小端,明确告诉你先发的是低字节还是高字节。

(4)在通信协议中,大小端是非常重要的,大家使用别人定义的通信协议还是自己要去定义通信协议,一定都要注意标明通信协议中大小端的问题。



版权声明:本文为shun1296原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。