转自:http://blog.csdn.net/luoyhang003/article/details/47338019

权声明:本文为博主原创文章,未经博主允许不得转载。(文章来源:http://blog.luoyuanhang.com)

 
 

在这篇文章中我们完成了以下内容:

  • 介绍 GDT
  • 介绍段描述符
  • 实现一个段描述符

介绍 GDT

GDT 是什么?

GDT(Global Descriptor Table)是一种数据结构,用来提供段式存储机制,这种机制是通过段寄存器和 GDT 中的描述符共同提供的。

在保护模式下,虽然现在的寄存器已经有32位的,但是我们依旧采用『段:偏移』的形式来寻址,只不过『段』的概念就相当于 GDT,段值仍然由16位的 cs、ds 等寄存器表示,但是这时段值仅仅是相当于一个索引,指向一个数据结构,这个数据结构就是 GDT一个表项,这个表项定义有段的起始地址、界限、属性等内容,这个表项也叫做描述符(descriptor)

描述符结构

  • 代码段和数据段描述符

    段描述符是一个8个字节的结构体,其中包含了段基址、段界限、段属性等信息

    • 段基址(32位):表示物理地址
    • 段界限(20位):表示段的长度(并不是地址,而是字节长度)
    • 段属性(12位):系统、门、数据等属性

    下面我们来实现这个结构体:

;描述符
;3个参数:
; 1.段基址:32位(4字节)
; 2.段界限:低20位
; 3.属性:12位(高字节中的低4位总是0) %macro Descriptor 3 ;定义宏Descriptor,有3个参数
dw %2 & 0FFFFh ;用参数2的低16位填充一个WORD
dw %1 & 0FFFFh ;用参数1的低16位填充一个WORD
db (%1 >> 16) & 0FFh ;用参数1的17-25位填充一个BYTE
dw ((%2 >> 8) & 0F00h) | (%3 & 0F0FFh) ;用参数2的17-21位以及参数3的1-8位和13-16位填充一个WORD
dw (%1 >> 24) & 0FFh ;用参数1的25-32位填充一个WORD
%endmacro
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

从代码中我们可以分析出各个参数的有效位:(F为有效)

  • 段基址:0xFFFFFFFF
  • 段界限:0x000FFFFF
  • 属性:0x0000F0FF

    我们得到了如下图所示的结构:

下面我们来介绍每一位的作用:

  • 第0、1字节:表示段界限
  • 第2、3、4字节:表示段基址
  • 第5、6字节比较复杂

    • 第5字节(从低到高):

      • 0-3:TYPE,说明存储段描述符所描述的存储段的具体属性
    S 段类型 类型值 说明
    0 数据段 0000 只读
    0 数据段 0001 只读、已访问
    0 数据段 0010 读/写
    0 数据段 0011 读/写、已访问
    0 数据段 0100 只读、向下扩展
    0 数据段 0101 只读、向下扩展、已访问
    0 数据段 0110 写、向下扩展
    0 数据段 0111 写、向下扩展、已访问
    0 代码段 1000 只执行
    0 代码段 1001 只执行、已访问
    0 代码段 1010 执行/读
    0 代码段 1011 执行/读、已访问
    0 代码段 1100 只执行、一致码段
    0 代码段 1101 只执行、一致码段、已访问
    0 代码段 1110 执行/读、一致码段
    0 代码段 1111 执行/读、一致码段、已访问
    1 系统段 0000 (未定义)
    1 系统段 0001 可用286TSS
    1 系统段 0010 LDT
    1 系统段 0011 忙的286TSS
    1 系统段 0100 286调用门
    1 系统段 0101 任务门
    1 系统段 0110 286中断门
    1 系统段 0111 286陷阱门
    1 系统段 1000 (未定义)
    1 系统段 1001 可用386TSS
    1 系统段 1010 (未定义)
    1 系统段 1011 忙的386TSS
    1 系统段 1100 386调用门
    1 系统段 1101 (未定义)
    1 系统段 1110 386中断门
    1 系统段 1111 386陷阱门
    • 4:S,说明描述符的类型。对于存储段描述符而言,S=1,以区别与系统段描述符和门描述符(S=0)。
    • 5-6:DPL,表示描述符特权级(Descriptor Privilege level),共2位。它规定了所描述段的特权级,用于特权检查,以决定对该段能否访问。
    • 7:P,存在(Present)位。
      • P=1 表示描述符对地址转换是有效的,或者说该描述符所描述的段存在,即在内存中
      • P=0 表示描述符对地址转换无效,即该段不存在。使用该描述符进行内存访问时会引起异常。
      • 第6字节
    • 0-3:段界限
    • 4:AVL,软件可利用位。80386对该位的使用未做规定,Intel公司也保证今后开发生产的处理器只要与80386兼容,就不会对该位的使用做任何定义或规定。
    • 5:0(未定义)
    • 6:D/B,D位是一个很特殊的位,在描述可执行段、向下扩展数据段或由SS寄存器寻址的段(通常是堆栈段)的三种描述符中的意义各不相同。 
      1. 在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小

        • D=1表示默认情况下指令使用32位地址及32位或8位操作数,这样的代码段也称为32位代码段;
        • D=0 表示默认情况下,使用16位地址及16位或8位操作数,这样的代码段也称为16位代码段,它与80286兼容。可以使用地址大小前缀和操作数大小前缀分别改变默认的地址或操作数的大小。
      2. 在向下扩展数据段的描述符中,D位决定段的上部边界 
        • D=1表示段的上部界限为4G
        • D=0表示段的上部界限为64K,这是为了与80286兼容
      3. 在描述由SS寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如PUSH和POP指令)使用何种堆栈指针寄存器 
        • D=1表示使用32位堆栈指针寄存器ESP;
        • D=0表示使用16位堆栈指针寄存器SP,这与80286兼容
    • 7:G,段界限粒度(Granularity)位

      • G=0 表示界限粒度为字节
      • G=1 表示界限粒度为4K 字节

      注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位


版权声明:本文为博主原创文章,未经博主允许不得转载。

文章来源:http://blog.luoyuanhang.com

非常好!!!【从头开始写操作系统系列】实现一个-GDT(1)【转】的更多相关文章

  1. 从头开始写框架(一):浅谈JS模块化发展

    博客申请下来已经过去一个月了,一直不知道写点什么,毕竟我的文笔不是很好orz. 不过既然申请下来了,不写点什么总是觉得很可惜.正好最近在自己写框架,就把自己的进程和一些心得体会分享出来吧. 写在前面: ...

  2. 用Qt写软件系列三:一个简单的系统工具(上)

    导言 继上篇<用Qt写软件系列二:QIECookieViewer>之后,有一段时间没有更新博客了.这次要写的是一个简单的系统工具,需求来自一个内部项目.功能其实很简单,就是查看当前当前系统 ...

  3. 给jdk写注释系列之jdk1.6容器(6)-HashSet源码解析&Map迭代器

    今天的主角是HashSet,Set是什么东东,当然也是一种java容器了.      现在再看到Hash心底里有没有会心一笑呢,这里不再赘述hash的概念原理等一大堆东西了(不懂得需要先回去看下Has ...

  4. 【百度地图-安卓SDK】从头开始写android程序

    [百度地图-安卓SDK]从头开始写android程序首先确保有这四个文件    安装jdk先安装android开发SDK(并不只是为eclipse服务的),即运行installer_r15-windo ...

  5. 给jdk写注释系列之jdk1.6容器(13)-总结篇之Java集合与数据结构

         是的,这篇blogs是一个总结篇,最开始的时候我提到过,对于java容器或集合的学习也可以看做是对数据结构的学习与应用.在前面我们分析了很多的java容器,也接触了好多种常用的数据结构,今天 ...

  6. 给jdk写注释系列之jdk1.6容器(12)-PriorityQueue源码解析

    PriorityQueue是一种什么样的容器呢?看过前面的几个jdk容器分析的话,看到Queue这个单词你一定会,哦~这是一种队列.是的,PriorityQueue是一种队列,但是它又是一种什么样的队 ...

  7. 给jdk写注释系列之jdk1.6容器(11)-Queue之ArrayDeque源码解析

    前面讲了Stack是一种先进后出的数据结构:栈,那么对应的Queue是一种先进先出(First In First Out)的数据结构:队列.      对比一下Stack,Queue是一种先进先出的容 ...

  8. 给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析

    前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈.      什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶 ...

  9. 给jdk写注释系列之jdk1.6容器(9)-Strategy设计模式之Comparable&Comparator接口

    前面我们说TreeMap和TreeSet都是有顺序的集合,而顺序的维持是要靠一个比较器Comparator或者map的key实现Comparable接口.      既然说到排序,首先我们不用去关心什 ...

随机推荐

  1. kinect数据读取

    http://blog.csdn.net/timebomb/article/details/7169372

  2. Basic motion detection and tracking with Python and OpenCV

    http://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/

  3. 面向对象编程(十二)——final关键字

    final关键字 Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类.非抽象类成员方法和变量. 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和 ...

  4. Linux 基本收集

    ifconfig eth0 192.168.1.223 切换到root账号开始是$符号输入su输入root密码转换成# 就变成了root账号 dr 查看盘符ls /etc/ 查看etc文件夹下面的文件 ...

  5. CPU boot up过程

    1.   CPU0 BOOT CPU1 BOOT 通过IPC互相通信 2.   CPU1 BOOT 完后,loop,等待IPC from CPU0 3.   cpu0 写IPC通知CPU1,cpu1 ...

  6. Java最全文件操作实例汇总

    本文实例汇总了Java文件操作.分享给大家供大家参考,具体如下: 1.创建文件夹 ? 1 2 3 4 5 6 7 8 9 10 11 //import java.io.*; File myFolder ...

  7. Leetcode: Number of Islands II && Summary of Union Find

    A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand oper ...

  8. iis access denied, you do not have permission.

    this kind of problems are usually caused by some IIS configuration issues, like application pool set ...

  9. 20145207《Java程序设计》第7周学习总结

    教材学习内容总结 一.Lambda -使用Lambda的特性可以去除重复的信息,以取得语法的简洁,增加程序代码的表达性.Lambda表达式本身是中性的,不代表任何类型的实例,同样的Lambda表达式, ...

  10. ant的那些闹挺事

    今日发现了一个问题,用ant+hudson去运行脚本代码时,突然ant报错: 即使我在ant的build文件中指定了basedir=“C:/Users/145064/.hudson/jobs/haix ...