数据通信--大小端转换

一、什么是大小端

内存地址小端模式存放内容大端模式存放内容
0x00000x780x12
0x00010x560x34
0x00020x340x56
0x00030x120x78

以0x12345678为例,可以看出。

大端,存放规则:12345678   显示规则:12345678

即低地址放高位,高地址放地位。

小端,存放规则:78563412   显示规则:12345678

即低地址放低位,高地址放高位。

 

二、哪些平台是大端、哪些平台是小端、为什么有大小端之分

2.1 常见的CPU架构的大小端举例(有待验证)

Big Endian : PowerPC 非NT、IBM、SUN SPARC、HP-PA UNIX、MIPS UNIX、RS/6000 UNIX、Motorola m68k

Little Endian : PowerPC NT、x86(Intel、AMD等)、DEC Alpha、HP-PA NT、MIPS NT、

其中ARM的大小端是可选的,网络tcp/ip 是大端。

2.2 为什么有大小端之分

在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的int型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。

因此就导致了大端存储模式和小端存储模式。

 

三、什么时候需要大小端转换、哪些数据需要判断大小端、如何判断大小端

3.1 什么时候需要大小端转换

大小端转换一般用在跨平台通信和资源共享上面,同一个平台上面的开发,它们的数据存放规则和显示规则是一致的,不需要考虑大小端相关问题。

仍然以0x12345678为例

小端到大端传输

如小端机器发送的int类型是0x12345678,那么数据的存放规则是 78 56 34 12

发送的时候从低地址开始读取,即发送出去是0x12345678,实际上是78 56 34 12

大端主机依次读取从低地址开始存放数据,低地址到高地址,大端机存放规则:    78563412

                                                                                      然后大端机的显示规则:0x78563412

这样看来,结果需要转换。

大端到小端传输

如大端机器发送:int类型的0x12345678,存放规则:12 34 56 78

发送的时候从低地址开始读取,即发送出去是0x12345678,实际上是:12 34 56 78

小端主机依次读取从低地址开始存放数据,低地址到高地址,小端机存放规则:    12345678

                                                                                       然后小端机的显示规则:0x78563412

这样看来,结果需要转换。

大端到大端传输

如大端机器发送:int类型的0x12345678,存放规则:12 34 56 78

发送的时候从低地址开始读取,即发送出去是0x12345678,实际上是:12 34 56 78

大端主机依次读取从低地址开始存放数据,低地址到高地址,大端机存放规则:    12345678

                                                                                      然后大端机的显示规则: 0x12345678

这样看来,结果不需要转换。

小端到小端传输

如小端机器发送:int类型的0x12345678,存放规则:78 56 34 12

发送的时候从低地址开始读取,即发送出去是0x12345678,实际上是:78 56 34 12

小端主机依次读取从低地址开始存放数据,低地址到高地址,小端机存放规则:   78563412

                                                                                      然后小端机的显示规则:0x12345678

这样看来,结果不需要转换。

3.2 哪些数据需要判断大小端

正如上面说的除了8bit的数据不需要进行数据转换,它只对应着一个地址单元,其余的short、int、long等类型都需要进行大小端判断。

 

3.3 如何进行大小端判断

最常见的就是联合体判断方法了,代码如下:

bool isBigEndian()  
{  
	union
	{  
		int a;  
		char b;  
	}num;  
	num.a = 0x12345678;  
	return ( num.b == 0x12 )   
}

 

四、大小端如何转换,常用方法是什么

大小端转换最有效也是最常见的方法就是移位法,如下:

#define __SWP16(A)   (( ((uint16)(A) & 0xff00) >> 8)    | \  
(( (uint16)(A) & 0x00ff) << 8))  

#define __SWP32(A)   ((( (uint32)(A) & 0xff000000) >> 24) | \  
(( (uint32)(A) & 0x00ff0000) >> 8)   | \  
(( (uint32)(A) & 0x0000ff00) << 8)   | \  
(( (uint32)(A) & 0x000000ff) << 24)) 

 

 

最后,出于效率考虑,大小端应该在最开始的通信过程中就要约定好,尽量减少系统资源的消耗。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值