本文共 2635 字,大约阅读时间需要 8 分钟。
转自:
权声明:本文为博主原创文章,未经博主允许不得转载。(文章来源: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)位
注意,界限粒度只对段界限有效,对段基地址无效,段基地址总是以字节为单位
版权声明:本文为博主原创文章,未经博主允许不得转载。
文章来源:
本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5714940.html,如需转载请自行联系原作者