标签:
转自:http://blog.csdn.net/luoyhang003/article/details/47338019
权声明:本文为博主原创文章,未经博主允许不得转载。(文章来源:http://blog.luoyuanhang.com)
在这篇文章中我们完成了以下内容:
GDT(Global Descriptor Table)是一种数据结构,用来提供段式存储机制,这种机制是通过段寄存器和 GDT 中的描述符共同提供的。
在保护模式下,虽然现在的寄存器已经有32位的,但是我们依旧采用『段:偏移』的形式来寻址,只不过『段』的概念就相当于 GDT,段值仍然由16位的 cs、ds 等寄存器表示,但是这时段值仅仅是相当于一个索引,指向一个数据结构,这个数据结构就是 GDT一个表项,这个表项定义有段的起始地址、界限、属性等内容,这个表项也叫做描述符(descriptor)
代码段和数据段描述符
段描述符是一个8个字节的结构体,其中包含了段基址、段界限、段属性等信息
下面我们来实现这个结构体:
;描述符
;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
从代码中我们可以分析出各个参数的有效位:(F为有效)
属性:0x0000F0FF
我们得到了如下图所示的结构:
下面我们来介绍每一位的作用:
第5、6字节比较复杂
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陷阱门 |
7:G,段界限粒度(Granularity)位
注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位
版权声明:本文为博主原创文章,未经博主允许不得转载。
非常好!!!【从头开始写操作系统系列】实现一个-GDT(1)【转】
标签:
原文地址:http://www.cnblogs.com/sky-heaven/p/5714940.html