30天自制操作系统开发笔记——GDT与IDT设置

所谓GDT即为global descriptor table意思为全局描述符,亦为全局段号记录表,因为CPU的段寄存器为16位(16为,32位和64位模式下的段寄存器都为16位)低3不能使用,所以能够使用的段号为13位为0~8191,为了表示一个段,需要包含以下信息

段的大小

段的起始地址

段的管理属性属性(禁止写入,系统专用等)

记录这三个信息需要8个字节

所以GDT总共包含的数据位8192*8=65536字节(64KB)

将每个段的描述信息设定好之后,连续的排列在内存的某个地方,然后将其起始地址和有效设定个数存入GDTR寄存器中

在设定GDT时,要设定段上限和地址值,赋值给一个名为GDTR的48位的寄存器而且唯一的方法是利用LGDT指令从内存中读取六个字节的赋值给GDTR寄存器,该寄存器的底16位表示段上限,为GDT的有效字节数-1(因为起始为0)剩下的四个字节表示GDT的开始地址,具体执行时,利用函数:

_load_idtr: ; void load_idtr(int limit, int addr);
MOV AX,[ESP+4] ; limit
MOV [ESP+6],AX
LIDT [ESP+6]
RET

调用函数load_idtr可以实现设置GDT

在设置每一个段的信息时,根据每个段的描述信息的三部分进行设置

段的地址,一个32位整数,称为基址,基址分为low(两字节),mid(1字节),high(1字节)3段,合起来为32位,之所以要分为3段是为了能和80286进行兼容,

段上限:表示一个段有多少个字节,但是段上限最大为4GB即为一个32位的数值,如果直接放进去,数值本身就要占用4个字节,再加上base,那么就无法存放属性信息了,所以段上限只能用20位,这样,段上限最大也只能指定到1MB,但是为了能制定为4GB的全部的内存,段的属性中设置了一个标志位为Gbit这个标志位为1时limit的单位不解释成字而解释为页(一页为4KB)这样就可以制定4GB的内存了

最后是段属性:占12位,称为段的访问权限属性记为ar,ar的高四位称为扩展访问权限,因为80286时还不存在,这四位由Gb00构成,G即为Gbit,b为1表示32位模式,为0表示16位模式

ar的低八位表示其访问权限,如

0x00:未使用的记录表

0x92:系统专用,可读写,不可执行

0x9a:系统专用,可执行,可读不可写

原文地址:https://www.cnblogs.com/caozhenhai/p/2923455.html