下面按照这三种模式出现的先后时间顺序来解释
1. 实模式
在早期的8086 CPU时,就是工作在这种模式。为了兼容性,后来所有的CPU在开机时,最先都是运行在实模式下。
1)在这种工作模式下,因为只有20根地址线,所以CPU的寻址空间最大为1M
2)实模式只支持单任务运行,不支持多任务并发执行
3)实模式不支持内存分页管理机制,所以通过16位的段地址*16+偏移地址算出来的地址就是“实实在在”的物理地址。所以按这种方式,最大的缺陷就是,当段地址或偏移地址出错时,就可能去修改了其他原不应该修改的内存,造成程序的crash或灾难性的后果。
4)实模式不支持优先级保护机制。所有指令相当于都运行在特权级,所以它可以执行特权指令。如果去看内核的setup.s的代码可以发现,386就是在实模式下先构建好GDT, LDT, IDT后,再初始化对应的GDTR, LDTR, IDTR等寄存器,最后全能TR0对应的位,进入保护模式。
2. 保护模式
1)从386后的CPU引入的保护模式新特性,此时地址总线扩展到了32位,所以CPU最大寻址空间达到了4G
2)保护模式支持多任务的并发执行,并且提供了硬件级别的任务切换功能
3)保护模式最重要的功能就是支持了内存分页管理和内存保护机制,这时,段寄存器中的值不在是段基址,而是GDT/LDT/IDT的一个index,通过该index从对应的段描述符表中取出对应段的一些属性,包括段基址、段限长等。然后由段基址和偏移地址组成线性地址。根据此线性地址和CR3(存的是页目录起始地址)做运算得出最终的物理地址。最大的好处就是,每个进程中使用的逻辑地址就是完全独立的,最后要通过OS把其转换成对应的物理地址,这样,应用程序就不用关心是否会踩到其他进程的地址空间了。因为OS已经做了保证。同时正因为内存保护机制,可以利用虚拟内存来运行最大的软件。
4)保护模式提供了优先级保护机制。一共是0~3,4个优先级,在linux中只用了0和3,分别对应最高特权级和最低特权级。内核代码运行在最高特权级,应用程序运行在最低特权级。这样就可以保证用户应用程序不会修改内核对应的数据。
3. 虚拟8086模式
其实是为了能够在保护模式下运行实模式程序而设定的。虚拟8086模式是以任务形式在保护模式下执行的,在386上可以同时支持由多个真正的386任务和虚拟8086模式构成的任务。在虚拟8086模式下支持多任务和内存分页。但对于内存的寻址还是采用和8086一样的寻址方式。