大小端和位域总结

今天看代码不小心又见着了位域,想着还不尴不尬的迷糊着,干脆这次查查资料弄清楚吧,总结点东西,下次有得看。


理解:
//××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
所谓大端序,就是当机器沿着地址从低地址向高地址读的时候,第一个读取到的字节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.csdn.net/solmyth/article/details/3251066

http://blog.csdn.net/goldenhunter/article/details/4508717


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值