1 关中断
2 加载 GDTR寄存器
3 设置CR0 寄存器
4 设置选择子,段内偏移
5 设置32位指令
6 重新设置数据段
7 设置GTD表首地址
os.c 代码
#include "os.h"
// 声明本地以下符号是全局的,在其它源文件中可以访问
.global _start
// 指定以下的代码生成16位的机器指令,这样才能在启动时的实模式下运行
.code16
// 以下是代码区
.text
_start:
jmp $0, $offset // 用于设置cs寄存器, cs:ip 不支持这种语法
offset:
mov $0, %ax
mov %ax, %ds
mov %ax, %ss
mov %ax, %es
mov %ax, %gs
mov %ax, %fs
mov $offset, %esp // 设置了栈顶指针
read_self_all:
mov $0x7e00, %bx // 读取到内存的位置
mov $0x2, %cx // 读取的扇区数量
mov $0x240, %ax // AH:读磁盘, AL:读取的数量
mov $0x80, %dx // 读取第一块磁盘
int $0x13 // 13号中断
jc read_self_all // 读取出错就反复读取
cli //关中断
lgdt [gdt_desc] //设置GDT 表的起始位置