本文参考
1.https://www.pediy.com/kssd/
2.http://blog.csdn.net/lanmolei814/article/details/44426651
大端、小端:
大小端是指CPU存储数据的方式,比如一个0x01020304这个整数,在WIN、Linux下在内存中的布局如下
[04][03][02][01]
低地址-->高地址
在UNIX下则是
[01][02][03][04]
低地址-->高地址
通俗的说,和WIN下的内存布局一致的就是小端,和UNIX下一致的就是大端。
其实在以前还出现过中端的的机型,不过这些机型也太“孤僻”了,已经落伍没人生产没人用了。
那么,如何判断一个机器是大端还是小端呢
在CSAPP中,有这么一段程序
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_byte(byte_pointer start,int len)
{
int i;
for(i=0;i<len;i++)
printf(" %.2x",start[i]);
printf("\n");
}
void show_int(int x)
{
show_byte((byte_pointer) &x,sizeof(int));
}
void show_float(float x)
{
show_byte((byte_pointer) &x,sizeof(float));
}
void show_pointer(void *x)
{
show_byte((byte_pointer) &x,sizeof(void *));
}
void test_show_bytes(int val)
{
int ival = val;
float fval = (float) ival;
int *pval = &ival;
show_int(ival);
show_float(fval);
show_pointer(pval);
}
int main()
{
test_show_bytes(12345);//对应十六进制是0x003039
return 0;
}
在windows机器上运行结果如下
可以看到0x3039是从低地址开始存的,我们称为小端
大小端编程检测
#include <stdio.h>
void checkdxd1(){ //通过读取同一地址的整型数据和字符数据来区别大端和小端
unsigned int data;
char *point=&data; //获取data的低地址,结果保存在低地址中
data=0;
*point= 0x22;
if(data==0x22)
{
printf("此处理器是小端!\n");
}
else if(data==0x22000000)
{
printf("此处理器是大端!\n");
}
else
{
printf("暂时无法判断机器类型!\n");
}
}
void checkdxd2(){ //通过联合体union的共享内存特性,来判断机器类型
union var
{
char str;
int data;
};
union var l;
l.data=0x01020304;
if(l.str==0x01)
{
printf("此处理器是大端!\n");
}
else if(l.str==0x04)
{
printf("此处理器是小端!\n");
}
else{
printf("暂时无法判断机器类型!\n");
}
}
void checkdxd3(){ //linux内核源码改写,使用联合体
static union
{
char a[4];
unsigned long ul;
} endian = {{'L', '?', '?', 'B'}};
#define ENDIAN ((char)endian.ul)
printf("%c\n", ENDIAN);//L是小端,B是大端
}
void checkdxd4() //强制类型转换
{
int i=1; // 1的16进制表示位0x00000001
char *p=(char *)&i;
//小端时,0x00000001的内存结构,[01][00][00][00] 低地址-->高地址,取&i地址则是取到低地址一个字节是[01]
//大端时,0x00000001的内存结构,[00][00][00][01] 低地址-->高地址,取&i地址则是取到低地址一个字节是[00]
if(*p==1)
{
printf("此处理器是小端!\n");
}
else{
printf("此处理器是大端!\n");
}
}
int main()
{
checkdxd1();
checkdxd2();
checkdxd3();
checkdxd4();
return 0;
}
linux下编译
gcc -o test test.c
运行
./test
至于怎么得到大端机器将在下一篇介绍