搞清一个机器是大端组织还是小端组织要依据对于 计算机内部的数据通信非常重要。虽然,目前我们大多数用到的数据格式都是统一的,但是了解这个概念对于一些在不同硬件平台上运行的可移值编程是很有帮助的。
所谓大端,是把字节从内存中的高位开始存储。 而小端正好相反。
当然,存储在何种位置,是依据CPU设计者的思维而定的,本质上没有任何区别。
比如,Mac机和Unix机就是采用了大端组织,而PC用的是小端组织。 但是有些网络协议也采用的是大端组织。
因此,在不同机器上,数据会对应着不同的格式。
小端组织的双字节排列: 数据的第一个半字节在低端存储地址, 然后依次往高端排列。
大端组织的双字节排列: 数据的第一个半字节在高端存储地址,然后依次往低端排列。
我们称这两种不同的数据排列方式为: 不同的性别。
所以当大端组织与小端组织进行通信时,它们的数据格式会不一致,导致出现错误的结果。
需要将它们都转换为一个统一的标准格式。
例如: 如果是通过网络传输数据,标准格式往往是大端格式。 而当通过通用串行总线(USB)传输数据的时候,标准格式就是小端组织。
镜像交换:
为了在大小端格式之间进行转换, 必须对对象中的各个字节进行镜像交换。这种交换是中心对称的。
对双字进行大端格式与小端格式的转换。 首先交换第零个字节和第三个字节,然后交换第一个字节与第二个字节
单个机器上的软件通信也会遭遇大端和小端的情况:
如: 有些程序会使用分立的字节来组合更大的对象,它们在这个大对象中给这些字节分配特定的位置。如果在一台大端机器上, 软件将最低字节放置在第零位到第七位处, 程序不会产生正确的结果。
用分立的字节来组成大的对象,可以使联合结构体。
考虑一下32位的联合结构体:
union
{
unsigned long bits32;
unsigned char bytes[4];
}theValue;
}theValue;
小端机器上, 四个分立的字节组成一个32位对象, 使用的代码如下:
theValue.bytes[0] = byte0;
theValue.bytes[1] = byte1;
theValue.bytes[2] = byte2;
theValue.bytes[3] = byte3;
但是在大端机器上,需要如下赋值:
theValue.bytes[0] = byte3;
theValue.bytes[1] = byte2;
theValue.bytes[2] = byte1;
theValue.bytes[3] = byte0;
如何判断是大端机器还是小端机器:
可以用如下代码:
theValue.bytes[0] = 0;
theValue.bytes[1] = 1;
theValue.bytes[2] = 0;
theValue.bytes[3] = 1;
isLittleEndian=theValue.bits32== 256;
如果等于,则是小端机器,如果大于则是大端机器