一、大小端模式
大端模式:数据的低位存储于内存的高位地址,数据的高位存储于内存的低位地址。
小端模式:数据的低位存储于内存的地位地址,数据的高位存储于内存的高位地址。
在32位处理器中,存储int型数据需要4个字节。数据0x12345678 大端模式和小端模式存储示意图如下。需要注意的是:无论是大端模式还是小端模式,数据0x12345678的地址都是内存中存储该数据的起始地址(即地址A)。
有的处理器系统采用了小端方式进行数据存放,如Intel的奔腾。有的处理器系统采用了大端方式进行数据存放,如IBM半导体和Freescale的PowerPC处理器。不仅对于处理器,一些外设的设计中也存在着使用大端或者小端进行数据存放的选择[1]。
下面看一道题目:写一个函数判断处理器是大端模式还是小端模式。
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 int
6 main()
7 {
8 int a = 0x12345678;
9 char *p = ( char * )&a;
10
11 if( *p == 0x78 ){
12 printf( "little\n" );
13 }
14 else{
15 printf( "big\n" );
16 }
17 }
思考:上面的代码作如下的修改,输出的结果和上次一样么?
修改后的代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int 6 main() 7 { 8 int a = 0xFF;//修改的地方 9 char *p = ( char * )&a; 10 11 if( *p == 0xFF ){//修改的地方 12 printf( "little\n" ); 13 } 14 else{ 15 printf( "big\n" ); 16 } 17 }
二、C语言中直接向内存赋值
无论处理器是大端模式还是小端模式,修改后的代码判断结果都是大端模式,原因在于第8行的赋值。“int a = 0xFF”,这种赋值方法是直接赋值给内存的。假设处理器是小端模式,由于计算机中数据的存储是以补码的方式存在的,所以p所指向的内存(一个字节)中存储的是负数的补码(0xFF最高位(第7位)是符号位)。0xFF的原码是0x81(0xFF按位取反后加1),最高位(第7位)是符号位,所以*p的值是-1,判断结果是大端模式。解决方法是把char *p 改为unsigned char *p。代码如下。
修改char *p为unsigned char *p:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int 6 main() 7 { 8 int a = 0xFF; 9 unsigned char *p = ( unsigned char * )&a;//修改的地方 10 11 if( *p == 0xFF ){ 12 printf( "little\n" ); 13 } 14 else{ 15 printf( "big\n" ); 16 } 17 }C语言直接向内存赋值,很好地体现了C语言的低极性。
参考文章:
[1] http://blog.youkuaiyun.com/dyllove98/article/details/8923298