今天看代码不小心又见着了位域,想着还不尴不尬的迷糊着,干脆这次查查资料弄清楚吧,总结点东西,下次有得看。
理解:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
所谓大端序,就是当机器沿着地址从低地址向高地址读的时候,第一个读取到的字节byte或位bit都是从最高权值(MSB:Most Significant Bit,最高有效位)或最高的一个byte;
地址低位————>地址增长方向 ————>地址高位
数据高位 | 1 0 0 0 1 1 1 1 | 0 1 0 1 0 0 0 0 | 数据低位
| byte 1 byte 2
|
/|/
pointer
指针指在第一个bit处,当 读取的时候依次读入1000111101010000 (依次读入 0x8f, 0x50)这个16位的数就是0x8f50
这样,在大端系统里,低地址存放MSB,高地址存放LSB。
msb:最高权值位,2^(n-1),俗称高位。
而低端序对应的16位数0x8f50 的存储方式为:
地址低位————>地址增长方向 ————>地址高位
数据低位 | 0 0 0 0 1 0 1 0 | 1 1 1 1 0 0 0 1| 数据高位
| byte 1 byte 2
|
/|/
pointer
读取的时候依次读入0 0 0 0 1 0 1 0 1 1 1 1 0 0 0 1;
这样,在小端系统里,低地址存放LSB,高地址存放MSB。
例子一:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
char* c;
struct bitfield {
int ia:3;
int ib:2;
int ic:3;
} field;
field.ia=4;
field.ib=2;
field.ic=2;
c=(char *) &field;
printf("%0x\n",*c);
printf("%d\n",*c);
struct里面,先声明的成员占有低地址
于是内存里是 0101 0100,以十六进制打印出来是0x54
于是内存里是 1001 0010,以十六进制打印出来是0x92
例子二:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
struct bitfield
{
char a1:1;
char a2:1;
char a3:1;
char a4:1;
char a5:1;
char a6:1;
char a7:1;
char a8:1;
}testbit;
testbit.a8 = 1;
先声明的成员占有低地址,所以数据填充如下:
地址低位————>地址增长方向 ————>地址高位
| a1 a2 a3 a4 a5 a6 a7 a8 |
小端系统,随地址低位读入lsb,用二进制表示为a8a7a6a5a4a3a2a1即10000000即-128;
大端系统,随地址低位读入msb,跟小端相反,即00000001。
例子三:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
struct tcphdr {
__u16 source;
__u16 dest;
__u32 seq;
__u32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4, //假设值为4(0100)
doff:4, //0101
fin:1, //1
syn:1, //1
rst:1, //1
psh:1, //1
ack:1, //1
urg:1, //0
ece:1, //1
cwr:1; //1
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4, //0101
res1:4, //0100
cwr:1,
ece:1,
urg:1, //0
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your defines"
#endif
__u16 window;
__u16 check;
__u16 urg_ptr;
};

理解:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
所谓大端序,就是当机器沿着地址从低地址向高地址读的时候,第一个读取到的字节byte或位bit都是从最高权值(MSB:Most Significant Bit,最高有效位)或最高的一个byte;
地址低位————>地址增长方向 ————>地址高位
数据高位 | 1 0 0 0 1 1 1 1 | 0 1 0 1 0 0 0 0 | 数据低位
| byte 1 byte 2
|
/|/
pointer
指针指在第一个bit处,当 读取的时候依次读入1000111101010000 (依次读入 0x8f, 0x50)这个16位的数就是0x8f50
这样,在大端系统里,低地址存放MSB,高地址存放LSB。
msb:最高权值位,2^(n-1),俗称高位。
而低端序对应的16位数0x8f50 的存储方式为:
地址低位————>地址增长方向 ————>地址高位
数据低位 | 0 0 0 0 1 0 1 0 | 1 1 1 1 0 0 0 1| 数据高位
| byte 1 byte 2
|
/|/
pointer
读取的时候依次读入0 0 0 0 1 0 1 0 1 1 1 1 0 0 0 1;
这样,在小端系统里,低地址存放LSB,高地址存放MSB。
例子一:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
char* c;
struct bitfield {
int ia:3;
int ib:2;
int ic:3;
} field;
field.ia=4;
field.ib=2;
field.ic=2;
c=(char *) &field;
printf("%0x\n",*c);
printf("%d\n",*c);
struct里面,先声明的成员占有低地址
于是内存里是 0101 0100,以十六进制打印出来是0x54
于是内存里是 1001 0010,以十六进制打印出来是0x92
例子二:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
struct bitfield
{
char a1:1;
char a2:1;
char a3:1;
char a4:1;
char a5:1;
char a6:1;
char a7:1;
char a8:1;
}testbit;
testbit.a8 = 1;
先声明的成员占有低地址,所以数据填充如下:
地址低位————>地址增长方向 ————>地址高位
| a1 a2 a3 a4 a5 a6 a7 a8 |
小端系统,随地址低位读入lsb,用二进制表示为a8a7a6a5a4a3a2a1即10000000即-128;
大端系统,随地址低位读入msb,跟小端相反,即00000001。
例子三:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
struct tcphdr {
__u16 source;
__u16 dest;
__u32 seq;
__u32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4, //假设值为4(0100)
doff:4, //0101
fin:1, //1
syn:1, //1
rst:1, //1
psh:1, //1
ack:1, //1
urg:1, //0
ece:1, //1
cwr:1; //1
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4, //0101
res1:4, //0100
cwr:1,
ece:1,
urg:1, //0
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your defines"
#endif
__u16 window;
__u16 check;
__u16 urg_ptr;
};

网卡发送每一个byte时从msb开始(不太确定,也有可能是lsb),则不管大小端其实发送的数据都一样。
参考链接:
http://blog.youkuaiyun.com/solmyth/article/details/3251066
http://blog.youkuaiyun.com/goldenhunter/article/details/4508717