最近在看linux内核书籍,在设置GDT表时又遇到了大小端的问题,在此做一下总结。供日后参考使用。

起源:

处理器的内存结构一般为一个地址上对应一个8bit的空间,也即能存储一个字节数据。如下图:


上面这款存储器为64K*8 ,其中64k为地址总数量,8是每个存储空间存储的bit位数。

即,这款存储器有64*1024个存储单元,每个单元可以存储一个字节的数据。

那么,如果我需要存储一个字节的数据,我找一个地址空间存储到里面就可以了。比如:0x0001处,存储了数据00001111 

不过,我要是想存储一个int型数据,我们假设int型数据有4个字节大小,假设我们存储的数据为0x12345678

就出现了以下两种方案:

地址偏移

大端模式

小端模式

0x00

12(OP0)

78(OP3)

0x01

34(OP1)

56(OP2)

0x02

56(OP2)

34(OP1)

0x03

78(OP3)

12(OP0)


大端:高位存在低地址,低位存在高地址;
小端:高位存在高地址,低位存在低地址;(intel的x86,ARM普遍都是属于小端,C51系列属于大端系列)

其中小端模式,低地址处存放低字节,高地址处存放高字节。符合一般逻辑思维。

大端模式,是低地址存放高字节,高地址存放低字节。比较符合人书写数字的习惯,先写高字节,后写低字节。

应用:
单个cpu是不会牵扯到这个概念的,当两个不同的cpu之间通过串行通讯方式进行通讯时,则要考虑此问题。例如,一个cpu为大端,一个cpu为小端。他们之间传输的数据,对方解析肯定是不正确的。所以,他们之间通讯要使用同一个字节序。
最典型的使用案例是网络传输字节序。
网络上传输的串行数据我们规定为大端字节序。
常用的字节转换函数有:
htons把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序

如果你使用的主机是小端模式,使用网络和其他主机传输信息时,要使用相应的转换函数。

cpu检测:
#define    Little_Endian    0
#define Big_Endian       1

  1. int CheckEndian(void)  
  1. {  
  1.     union check  
  1.     {  
  1.         int  Word;  
  1.         char Half;  
  1.   
  1.     } Endian;  
  1.   
  1.     Endian.Word=1;  
  1.   
  1.     if(1 == Endian.Half)  
  1.         return Little_Endian;  
  1.     else   
  1.         return Big_Endian;  
  1. }  

此程序,利用联合体的性质,判断出CPU大小端特性。

版权声明:本文为博主原创文章,未经博主允许不得转载。