谈谈bit位序的问题

Linux内核里面有下面代码:

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,
        version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,
          ihl:4;
#else
#error    "Please fix <asm/byteorder.h>"
#endif
    __u8    tos;
    __u16    tot_len;
    __u16    id;
    __u16    frag_off;
    __u8    ttl;
    __u8    protocol;
    __u16    check;
    __u32    saddr;
    __u32    daddr;
    /*The options start here. */
};

 

Linux里面区分了bit位序,对于大多数CPU构架来说,bit位序与字节序是对应的,对于少数偏僻、不常用的cpu,可能会出现bit位序与字节序不一致的情况。由于目前Linux支持的系统还未出现本情况,所以目前Linux的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD与__BIG_ENDIAN和__LITTLE_ENDIAN是一一对应的,一致的。

 

另外,下面写一段c测试代码,并分析汇编代码,验证bit位序在小头序上的存贮:

#include <stdio.h>

struct hdr {
    unsigned char l:1;
    unsigned char m:3;
    unsigned char h:4;
};

 

/* intel,little endian下,h放高位,l放地位,下面是验证代码 */

/* 大字节序由于本人机器上没有mips的gcc编译环境,暂无法提供 */

 

main()
{
    unsigned char c;   /* c为局部变量,在堆栈中分配 */
    struct hdr *pst;

    pst = (struct hdr *)&c;
    printf("%x%x%x", pst->l, pst->m, pst->h); /* 汇编的压栈顺序是从右到左,cdecl方式 */
}

 

关键汇编如下:

  80483d9:    0f b6 44 24 1f           movzbl 0x1f(%esp),%eax   #从堆栈中取出c的值放到eax
 80483de:    c7 04 24 d4 84 04 08     movl   $0x80484d4,(%esp)
 80483e5:    89 c2                    mov    %eax,%edx
 80483e7:    c0 ea 04                 shr    $0x4,%dl     #取c右移4位后放入dl
 80483ea:    0f b6 d2                 movzbl %dl,%edx  #dl扩展到一个long的edx,printf接受的变参是以word为单位
 80483ed:    89 54 24 0c              mov    %edx,0xc(%esp)  #第一个参数压栈,也就是pst->h
 80483f1:    89 c2                    mov    %eax,%edx
 80483f3:    83 e0 01                 and    $0x1,%eax     #c取最后一个bit放入eax
 80483f6:    d0 ea                    shr    %dl                    #c右移1位
 80483f8:    83 e2 07                 and    $0x7,%edx      #取edx低3位
 80483fb:    89 54 24 08              mov    %edx,0x8(%esp)   #第二个参数压栈,也就是pst->m
 80483ff:    89 44 24 04              mov    %eax,0x4(%esp)    #第三个参数压栈,也就是pst->l
 8048403:    e8 ec fe ff ff           call   80482f4 <printf@plt>

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值