最近在看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类型从网络序转换到主机序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序
如果你使用的主机是小端模式,使用网络和其他主机传输信息时,要使用相应的转换函数。
cpu检测:
#define Little_Endian 0
#define Big_Endian 1
- int CheckEndian(void)
- {
- union check
- {
- int Word;
- char Half;
- } Endian;
- Endian.Word=1;
- if(1 == Endian.Half)
- return Little_Endian;
- else
- return Big_Endian;
- }
版权声明:本文为博主原创文章,未经博主允许不得转载。
转载于:https://blog.51cto.com/zhanglianpin/1675041