Ale*_*hol 6 x86 assembly nasm osdev
我正在开发一个小型操作系统,它将为每个进程使用单独的本地描述符表.我知道我需要使用该lldt指令从我的GDT加载LDT段.我已经使用有效的GDT在保护模式下运行我的内核,但我无法弄清楚我的LDT的GDT条目应该是什么样子.我知道它的基地址应该指向我的LDT,但我不知道特权级别和其他属性应该是什么.这是代表我的GDT中的LDT条目的NASM代码:
localTable equ $-gdt ; GDT entry #5 (selector 20h)
dw 0x1FF ; limit to 64 descriptors
dw 0x8000 ; base address
db 0x0
db 0x89 ; probably incorrect...
db 0x1f ; possibly incorrect...
db 0x0
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉NASM语法,则此表条目的基址为0x8000,限制为511(总共512个字节,或64个条目).我在i486程序员的参考手册中已经阅读了关于GDT和LDT的部分,但我无法完全理解我的GDT条目应该是什么样子.
无论如何,我像这样加载LDT:
mov ax, 0x20
lldt ax
Run Code Online (Sandbox Code Playgroud)
此代码使处理器生成一般保护错误(我通过中断处理它).我想知道两件事:
1)我是否在GDT中正确描述了我的LDT?如果没有,需要改变什么?2)LLDT由于LDT本身存在无效选择器,指令是否会失败?我读了LLDT指令规范,在我看来它甚至没有读取LDT的内存,但我只是想确定LLDT没有失败,因为我的LDT数据中有一个拼写错误.
好吧,我明白了。我使用的类型 ( 1001b) 不是我需要的。我发现类型 2 ( 10b) 用于 LDT 条目。作为记录,此信息位于i486 微处理器程序员手册第 6 章第 4 页中。我的功能 GDT 条目如下所示:
localTable equ $-gdt ; GDT entry #5 (selector 20h)
dw 0x1FF ; limit to 64 descriptors
dw 0x8000 ; base address
db 0x0
db 0x82 ; 10000010b (segment present set, WTM)
db 0x1f
db 0x0
Run Code Online (Sandbox Code Playgroud)