Skip to content

08 重新设置 idt 和 gdt

你好,我是闪客。

上一讲咱们说到,CPU 进入了 32 位保护模式,最后是跳到了内存地址 0 处开始执行代码。

0 位置处存储着操作系统全部核心代码,是由 head.s 和 main.c 以及后面的无数源代码文件编译并链接在一起而成的 system 模块,如图所示:

图片

今天我们一起看看,正式进入 C 语言写的 main.c 之前,head.s究竟写了点啥?

重新设置栈

head.s 文件很短,我们一点点看。

_pg_dir:
_startup_32:
    mov eax,0x10
    mov ds,ax
    mov es,ax
    mov fs,ax
    mov gs,ax
    lss esp,_stack_start

你有没有注意到开头有个标号 _pg_dir?这个表示页目录,之后在设置分页机制时,页目录会存放在这里,也会覆盖这里的代码,你这里有个印象就行。

再往下连续五个 mov 操作,分别给 ds、es、fs、gs 这几个段寄存器赋值为 0x10,根据段描述符结构解析,表示这几个段寄存器的值为指向全局描述符表中的第二个段描述符,也就是数据段描述符。

最后 lss 指令相当于让 ss:esp 这个栈顶指针,指向了 _stack_start 这个标号的位置。还记得图里的那个原来的栈顶指针在哪里吧?往上翻一下,0x9FF00,现在要变咯。