简介
上一节我们实现了从内核加载器中加载其它扇区代码并执行,但始终工作在实模式状态下。内存寻址方式和8086相同,由16位段寄存器的内容乘以16(10H)当做段基地址,加上16位偏移地址形成20位的物理地址,最大寻址空间1MB,最大分段64KB。
保护模式与实模式相比地址转换方式差异较大:
实模式下的地址转换方式,假设我们在ES中存入0x1000,DI中存入0xFFFF,那么ES:DI=0x1000*0x10+0xFFFF=0x1FFFF。
保护模式下ES:DI=全局描述符表中第0x200项描述符(一个描述符8个字节)给出的段基址+0xFFFF
1、描述符
保护模式下引入描述符来描述各种数据段,所有的描述符均为8个字节(0-7),由第5个字节说明描述符的类型,类型不同,描述符的结构也有所不同。若干个描述符集中在一起组成描述符表,而描述符表本身也是一种数据段,也使用描述符进行描述。“地址转换”由描述符表来完成,描述符表是一张地址转换函数表。
2、选择子
选择子是一个2字节的数,共16位,最低2位表示RPL,第3位表示查表是利用GDT(全局描述符表)还是LDT(局部描述符表)进行,最高13位给出了所需的描述符在描述符表中的地址。(注:13位正好足够寻址8K项)有了以上三个概念之后可以进一步工作了,现在程序的运行与实模式下完全一样!各段寄存器仍然给出一个“段值”,只是这个“假段值”到真正的段地址的转换不再是“左移4位”,而是利用描述符表来完成。
3、80x86系列中引入了两个新寄存器GDTR和LDTR,其中GDTR用于表示GDT在内存中的段地址和段限(就是表的最大偏移上限),因此GDTR是一个48位的寄存器,其中32位表示段地址,16位表示段限。
目标
实现实模式到保护模式的切换需要使用汇编语言实现,boot.s文件修改如下
;能用于操作内存的寄存器只能是bx、bp、si、di
;0x7c00--0x7dff 这512字节用于启动区
;对内存的访问都必须指定段寄存器ÿ