80x86描述符总结及解析描述符的小程序

一、描述符的分类

这里写图片描述

二、描述符格式

1、数据段描述符

这里写图片描述

2、代码段描述符

这里写图片描述

3、LDT段描述符

这里写图片描述

4、TSS段描述符

这里写图片描述

5、调用门描述符

这里写图片描述

6、中断门描述符

这里写图片描述

7、陷阱门描述符

这里写图片描述

8、任务门描述符

这里写图片描述

三、解析描述符的小程序

#include <stdio.h>

//定义描述符中的低32位
struct seg_des_low_word
{
    unsigned int limit_0_15:16;
    unsigned int base_0_15 :16;

};
//定义描述符中的高32位(通用格式)
struct seg_des_high_word
{
    unsigned int base_16_23 :8;
    unsigned int type       :4;
    unsigned int s          :1;
    unsigned int dpl        :2;
    unsigned int p          :1;
    unsigned int limit_16_19:4;
    unsigned int avl        :1;
    unsigned int l          :1;//保留给64位处理器使用
    unsigned int d_b        :1;
    unsigned int g          :1;
    unsigned int base_24_31 :8;
};


void parse_seg_des(unsigned int low_dw, unsigned int hig_dw)
{

    struct seg_des_low_word *pl 
        =(struct seg_des_low_word*)&low_dw;

    struct seg_des_high_word *ph
        =(struct seg_des_high_word*)&hig_dw;

    unsigned int type = ph->type;

    int offset = (hig_dw & 0xFFFF0000) | (low_dw & 0x0000FFFF);


    unsigned int seg_base = 
        (ph->base_24_31<<24)|(ph->base_16_23<<16)|pl->base_0_15;//拼接基地址字段

    unsigned int seg_limit =
        seg_limit = (ph->limit_16_19<<16)|pl->limit_0_15;//拼接段限长字段

    int system = ph->s;

    //下面的字段输出是不是很方便?这就是位字段的好处之一
    printf("P = %d\n",ph->p);
    printf("DPL = %d\n",ph->dpl); //P和DPL是每个段描述符都有的

    if(system == 0) //system segment
    {
        if(type == 9 || type==11 || type==2) //==的优先级高于||
        {
            //print base address,limit,G
            printf("base address = %#X\n",seg_base);
            printf("limit = %#X ,",seg_limit);

            if(ph->g == 1)
                printf("以4KB为单位\n");
            else
                printf("以B为单位\n");
        }

        if(type == 9)
            printf("TSS段,不忙\n");
        else if(type == 11)
            printf("TSS段,忙\n"); 
        else if(type == 5)
            printf("任务门,TSS段选择子 = %#X\n",pl->base_0_15);
        else if(type == 6)
            printf("16位中断门,段选择子 = %#X,偏移 = %#X\n",pl->base_0_15,offset);
        else if(type == 14)
            printf("32位中断门,段选择子 = %#X,偏移 = %#X\n",pl->base_0_15,offset);
        else if(type == 7)
            printf("16位陷阱门,段选择子 = %#X,偏移 = %#X\n",pl->base_0_15,offset);
        else if(type == 15)
            printf("32位陷阱门,段选择子 = %#X,偏移 = %#X\n",pl->base_0_15,offset);
        else if(type == 12)
            printf("调用门,段选择子 = %#X,偏移 = %#X , 参数个数 = %d\n",pl->base_0_15,offset, hig_dw & 0x1F);
        else if(type == 2)
            printf("LDT描述符\n");
    }
    else //data or code segment
    {
        printf("base address = %#X\n",seg_base);
        printf("limit = %#X ,",seg_limit);

        if(ph->g == 1)
            printf("以4KB为单位\n");
        else
            printf("以B为单位\n");

        if(type & 0x08 ) //代码段,分析C,R,D      
        {
            printf("代码段,");

            if(ph->d_b == 1) //D=1
                printf("默认操作数大小为32位\n");
            else
                printf("默认操作数大小为16位\n");

            if(type & 0x04) //C=1
                printf("一致性,");
            else
                printf("非一致性,");

            if(type & 0x02) //R=1
                printf("可读\n");
            else
                printf("不可读\n");
        }
        else    //数据段,分析B,E,W
        {
            printf("数据段,");

            if(ph->d_b == 1) //B=1
                printf("栈段使用ESP,ESP最大为0xFFFFFFFF\n");
            else
                printf("栈段使用SP,SP最大为0xFFFF\n");

            if(type & 0x04) //E=1
                printf("向下扩展,");
            else
                printf("向上扩展,");

            if(type & 0x02) //W=1
                printf("可写\n");
            else
                printf("不可写\n");
        }
    }

}

int main(void)
{
    printf("please input the segment descriptor,format: [low dword] [high dword]\n");
    printf("example:\n");
    printf("000003ff 00c0fa00\n");
    printf("The Descriptor:\n");

    unsigned int l_dword = 0;
    unsigned int h_dword = 0;

    //请求用户输入描述符,先是低32位,再是高32位
    scanf("%x" "%x",&l_dword,&h_dword);
    printf("----------------------\n");
    parse_seg_des(l_dword,h_dword);

    return 0;
}

以上代码编译后运行:

please input the segment descriptor,format: [low dword] [high dword]
example:
000003ff 00c0fa00
The Descriptor:

提示用户输入段描述符,先输入低32位,再输入高32位。注意:中间以空格分开,且以16进制输入,前面不用加“0x”。
比如,用户输入:

80000002 c0920b

回车后得到:

——————–
P = 1
DPL = 0
base address = 0XB8000
limit = 0X2 ,以4KB为单位
数据段,栈段使用ESP,ESP最大为0xFFFFFFFF
向上扩展,可写

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值