大小端的问题(转)
大小端的不同主要影响两个方面,而且它们本质上原因是相同的。它们分别是字节序和比特序
字节序:
字节序是指占用内存多于一个字节类型的数据在内存中的存放顺序,有小端、大端两种字节顺序。小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;大端字节序相反。网络字节序为大端字节序。
不同体系结构的CPU有不同的字节序类型:INTEL的X86平台使用小端法,IBM、Motorola、Sun Microsystem等大多数微处理器则使用大端法,还有部分微处理器可以由用户自己设置是使用大端法还是小端法,如ARM、MIPS、PowerPC等。
比特序:
在说明比特序之前,先说说位域的概念:
些信息在存储时,并不需要占用一个完整的字节,而只需占一个或几个二进制位。为了节省存储空间,并使处理简便,C语言提供了一种数据结构,称为“位域”或“位段”。
关于位域,有如下相关规则:
使用规则:
1. 一个位域必须存储在定义它的一个数据类型内部,不能跨越该数据类型。如位域所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。
2. 由于位域不允许越过定义它的数据类型,因此位域的长度不能大于定义它的数据类型的长度。
3. 位结构总长度(位数), 是各个位成员定义的位数之和再向最大结构成员对齐。
4. 位结构成员可以与其它结构成员一起使用。
压缩存储规则:
1. 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2. 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3. 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4. 如果位域字段之间穿插着非位域字段,则不进行压缩;
整个结构体的总大小为最宽基本类型成员大小的整数倍。
说完位域,继续比特序的话题,与字节序类似,不同体系结构的CPU会按不同的方法来解释高低比特的顺序。小端的CPU将低位数据存放在内存低地址处,高位数据存放在内存高位处;大端的CPU相反。
大/小端区别的本质是由于CPU的数据引脚和系统地址总线的连接方向的不同。也就是说,高地址/低地址的区别不仅体现在“字节序”上,还体现在“比特序”上,只不过因为系统屏蔽了“比特序”的一些细节,所以在没有用位域对字节进行进一步划分的情形下,看起来问题仅仅是字节之间的顺序问题了。
这样,比特序相关的问题,可以从两个角度结合分析:先从系统地址总线的角度来分析数据的存放,然后从CPU的数据引脚的角度来解析数据。假设固定总线上的比特地址,从0比特到7比特的内存数据是 0000 0001。那么,小端的CPU读到的值就是0x80,而大端的CPU读到的值就是0x01。
实际应用中要注意java语言(Java的硬件无关性)和网络数据使用的都是大端形式的数据。C语言中和系统CPU相关。需要注意C语言的位域中,每个field是严格按照bit地址从低到高排列的,不会随大小端变化。
我们常用的intel x86系列主机CPU均为小端模式。
这次写的有点多,累啊~~~就这样了,休息,休息一下 ^_^
浙公网安备 33010602011771号