分类: LINUX
2013-01-07 18:37:34
操作系统大小端模式判断问题
区别
小端模式:高字节存放在内存的高地址,低字节存放在内存的低地址
大端模式:高字节存放在内存的低地址,低字节存放在内存的高地址
注意:
1. 单位是字节(8位),所以0x34 12(0x开头表示16进展,所以每一个数表示4位(bit),两个数表示一个字节,所以34是一个字节,12也是一个字节),要么顺序为34 12,要么为12 34,只有这两种情况,不会出现43或者21,因为单位是字节!(字节里面的顺序无论是大端还是小端是不变的)
2. 高字节,低字节指的是数里面的高位,低位,比如0xff12,那么ff是高字节,12是低字节
3. 高地址,低地址指的是内存地址,对0x1000,0x1001而言,0x1000是低地址,0x1001是高地址
举例
有十六进制数0x12345678,则
内存地址(单位字节) |
大端 |
小端 |
0x00 |
12 |
78 |
0x01 |
34 |
56 |
0x02 |
56 |
34 |
0x03 |
78 |
12 |
再次提醒:大小端的差异是针对字节而言的,字节里面的二进制数据是不变的,所以不会出现21或43或65或87
作用
至少你的知道内存的哪个地址存放的是哪些东西,比如你有一个int(4字节)型变量int a=0xff11,假设&a=0x1000(这是内存地址),而你的操作系统时小端模式,那你肯定就应该知道
Int占4字节,所以int a=0xff11实际上是0x00 00 ff 11,而又是小端内存存放(高字节存放在内存的高地址,低字节存放在内存的低地址,0x00 00 ff 11中,00 是高字节,11是最低的字节,这就相当于千位,百位,十位,个位,谁是高字节一会儿就记住了),所以
0x1000 存放的是11
0x1001 存放的是ff
0x1002 存放的是00
0x1003 存放的是00
通过这个,你可以很清楚的通过指针偏移多少字节来读取这个int(或其它任何类型,这里仅举例)中的任何一个字节去随便做你想做的事
判断程序
那如何判断你的系统时大端还是小端呢,我们可以按照定义来编程
我们知道char 是一个字节,int一般是4个字节(记得以前学校里面教材上是32位的2字节,这个不重要,你可以加一个sizeof(int)来判断下到底几字节)
干脆编一个程序不区分int是2字节还是4字节的,我们可以
Int a=0xff11,简单这样赋值,其余不管,如果int是2字节,那么其实a=0xff11;如果int是4字节,那么其实a=0x00 00 ff 11,无论如何,低字节都是0x11,如果是小端,则0x11存放在a变量的首地址开始的第一个字节(小端是低字节低地址嘛),否则0x11存放在变量a的最高地址
所以
可以新建int变量a
Int a=0xff11
Char *p=(char *)&a;获取a的首地址,强制转换为char指针,直接赋值给char类型的指针p(因为char是1个字节大小)
如果 (int)(*p)==0x11,则是小端,即*p先去拿这8位数据,然后转化为我们之前的int型,如果等于0x11,说明这个低字节0x 11确实存在了低地址(变量的首地址是这个变量的最低地址了)
故完整程序如下
#include
int main(){
int x=0xff11;
char *p=(char *)&x;
if((int)(*p)==0x11)
printf("little end!\n");
else
printf("big end!\n");
return 0;
}
运行结果,,我们的服务器是小端的。。
还有其它的判断大小端方法,比较常用的还有利用union结构体特性来判断的,因为union是共享内存地址的,所以
union a{
int a,
char b
},中的a,b首地址相同,给a赋值0xff11,然后去读b,因为b只能读取一个字节,而b又处于union体的首地址这个时候如果(int)a.b==0x11,则是小端,因为低地址存放低字节嘛。