第4章 80x86保护模式及其编程(2)

第4章 80X86保护模式及其编程(2)

4.6 中断和异常处理

在这里插入图片描述
中断:(Interrupt);异常(Exception);中断处理程序(interrupt handler);异常处理程序(execption handler)。
系统硬件使用中断来处理外部事件。
当处理器在执行一条指令时,检测到一个出错条件,此时发生异常。包括违反保护机制、页错误以及及其内部错误。
80x86可以透明的处理发生的中断和异常事件。

4.6.1 异常和中断向量

在这里插入图片描述
通过中断向量查找中断描述符表从而定位异常或中断的处理程序入口位置。
向量号范围:0-255,其中0到31保留作为80X86处理器定义的异常和中断。
32-255用于用户定义的中断,常用于外部IO设备。表4-8给出为80X86定义的异常和NMI中断分配的向量。
NMI中断:non-maskable interrupt,不可屏蔽中断。参考Non-maskable interrupt

在这里插入图片描述

4.6.2 中断源和异常源

4.6.2.1 中断源

两种中断源:

  • 外部(硬件产生)的中断;
  • 软件产生的中断

在这里插入图片描述
外部中断通过INTR和NMI两个引脚接收,然后读取外部中断控制器提供的中断向量号:

  • INTR接收的中断,可屏蔽中断,通过标志寄存器EFLAGS中的IF标志屏蔽。
  • NMI接收的中断,不可屏蔽中断。中断号2。

也就是通过INTR或NMI引脚来通知处理器有中断了,通过外部中断控制器来读取是哪个中断。

软件中断通过 INT n指令产生。通过软件方式产生NMI中断,会调用NMI的中断处理程序,但是不会激活处理器的硬件处理(应该是因为硬件上NMI引脚没有收到信号)。标志寄存器中的IF位不能屏蔽软件中断。

4.6.2.2 异常源

两个:

  • 处理器检查到的程序错误异常
  • 软件产生的异常

异常可以被细分为故障(faults),陷阱(traps)和中止(aborts)
指令INTO、INT 3和BOUND指令可以来从软件中产生异常。INT3指令会产生一个断点异常。

INT n指令模拟指定的异常时,处理器不会像硬件引起的异常一样将一个错误号压入堆栈。对于会产生错误码的异常,异常处理程序会试图从堆栈中弹出错误码,此时会弹出EIP,导致返回位置错误。

4.6.3 异常分类

三类:故障(faults),陷阱(traps)和中止(aborts)
在这里插入图片描述

4.6.4 程序或任务的重新执行

为了保证让程序或任务在一个异常或中断处理完之后能够重新恢复执行,除了终止(abort)之外的所有异常都能够报告精确的指令位置,并且所有中断保证是在指令边界上发生。

  • 对于故障(fault)类异常,处理器产生异常时保存的返回指针指向出错指令。返回时原出错指令被重新执行。常见的例子是页面故障(Page-fault)异常。即访问不在内存中的页面。
  • 对陷阱(trap)类异常,处理器产生异常时保存的返回指针指向引起陷阱操作的后一条指令。
  • 中止(abort)类异常不支持可靠的重新执行程序或任务。

中断会严格的支持被中断程序的重新执行。
在这里插入图片描述

4.6.5 开启和禁止中断

通过设置标志寄存器EFLAGS的中断允许标志IF(Interrupt enable flag)可以禁止INTR引脚上收到的可屏蔽中断。IF=0,中断禁止;IF=1,中断打开。
IF标志不应影响不可屏蔽中断NMI,不影响异常。
在这里插入图片描述

4.6.6 异常和中断的优先级

异常和中断的优先级如表4-9所示。处理器会首先处理最高优先级类中的异常或中断。低优先级的异常会被丢弃,低优先级的中断会保持等待。 当中断处理程序返回到产生异常和/或中断的程序或任务时,被丢弃的异常会重新发生。
在这里插入图片描述

4.6.7 中断描述符表

中断描述符表IDT(Interrupt Descriptor Table)将每个异常或中断向量分别与它们的处理过程联系起来。IDT中描述符长度也为8字节。异常或中断的向量号*8即可构成IDT表中的一个索引值。最多256个描述符。
IDT表可以驻留在线性地址空间的任何地方,使用IDTR寄存器来定位。IDTR结构:
在这里插入图片描述
16位限长值以字节为单位,最大为256*8
LIDT:加载到IDTR寄存器,CPL需为0,常被用于创建IDT时的操作系统初始化代码中。
SIDT:把IDTR中的基地址和限长内容复制到内存中,可以在任何特权级上执行。

4.6.8 IDT描述符

IDT表中可以存放三种类型的的门描述符:

  • 中断门(Interrupt gate)描述符
  • 陷阱门(Trap gate)描述符
  • 任务门(Task gate)描述符
    其描述符分别为:
    在这里插入图片描述

4.6.9 异常与中断处理

处理器对异常和中断处理过程的调用操作方法与使用CALL指令调用程序过程和任务的方法类似。
在这里插入图片描述
所以中断或异常的执行流程为:根据中断号在IDT中找到描述符,根据描述符在GDT、LDT中找到需要执行的代码,开始执行。

IDT中的中断门、陷阱门和任务门以及GDT中的中断门,陷阱门和任务门各自什么时候使用呢?
比较一下其描述符结构发现IDT中的描述符没有参数个数。这个后面再研究一下。

在这里插入图片描述
在这里插入图片描述
特权级发生变化则需要进行堆栈切换,如果特权级不发生变化则不需要进行堆栈切换。TSS段保存在哪里呢?应该和TR寄存器有关系,这个后面再看。

为了从中断处理过程中返回,处理过程必须使用IRET指令。IRET指令和RET指令类似,但是IRET指令还会把保存的寄存器内容恢复到EFLAGS中。

1.异常和中断处理过程的保护
处理器不允许把控制转移到比CPL更低特权级代码段的中断处理过程中。与调用门不同之处在于:

  • 中断和异常向量没有RPL
  • 只有当一个异常或中断是利用INT n,INT3或INTO指令产生,即使用软件方式产生时,处理器才会检查中断或陷阱门中的DPL。对硬件产生的中断和处理器检查到的异常,即硬件方式产生,处理器会忽略中断门和陷阱门中的DPL。

违反特权级保护的方法:

  • 异常或中断处理程序可以存放在一个一致性代码段中。
  • 处理过程可以放在具有特权级0的非一致代码段中。

2.异常和中断处理过程的标志使用方式
在这里插入图片描述
TF标志:跟踪标志(Trap Flag),位8。详见本书4.1.1节。

3.执行中断处理程序的任务

GDT表中描述符类型分为普通段描述符和系统段描述符。TSS段是系统段描述符的一种。详见本书4.3.4-4.3.6节。

4.6.10 中断处理任务

当通过IDT中任务门来访问异常或中断处理过程时就会导致任务切换。使用单独的任务来处理异常或中断有如下好处:

  • 被中断程序或任务的完整上下文会被自动保存;
  • 在处理异常或中断时,新的TSS可以允许处理过程使用新特权级0的堆栈。
  • 通过使用单独的LDT给中断或异常处理任务独立的地址空间,可以把它与其他任务隔离开来。
    其劣势在于:任务切换时需要对大量的机器状态进行保存,使得它比使用中断门的响应速度要慢,导致中断延时增加。

IDT中的任务门会引用GDT中的TSS描述符。如下图所示。

在这里插入图片描述
IDT中任务门的描述格式见4.6.8节及图4-27.

4.6.11 错误码

当异常条件与一个特定的段相关时,处理器会把一个错误码压入异常处理过程的堆栈上。其格式如图4-31。其最低位三个标志为:

  • 外部时间ext(External event),位0。当置位时,表示执行程序以外的事件造成了异常,例如硬件中断。
  • 描述符位置IDT(Descriptor location),位1,置位时,表示错误码的索引部分指向IDT中的一个门描述符。复位时,表示指向GDT或LDT中的一个段描述符。
  • GDT/LDT表选择符TI,位2。当IDT复位时,TI=1,指向LDT中的一个描述符;当TI=0,表示GDT中的一个描述符。

在这里插入图片描述
表示错误是由某个特定段造成的。

页故障(Page fault)异常的错误码格式如下:
在这里插入图片描述
错误码可以用于定位发生错误的段或页面。
错误码不会被IRET指令自动弹出堆栈,因此中断处理程序在返回之前必须清除堆栈上的错误码。外部硬件中断或程序执行INT n指令产生的异常并不会把错误码压入堆栈中。

4.7 任务管理

任务(Task)是处理器可以分配调度、执行和挂起的一个工作单元。它可以用于执行程序、任务或进程、操作系统服务、中断或异常处理过程和内核代码。

80X86提供了一种机制,这种机制可以用来保存任务的状态、分派任务执行以及从一个任务切换到另一个任务。当工作在保护模式下,处理器所有运行都在任务中。即使是简单系统也必须起码定义一个任务。更为复杂的系统可以使用处理器的任务管理功能来支持多任务应用。

(注意,任务管理功能是由处理器本身提供的,也就是有相关硬件支持的,在我之前的学习中一知半解,一直搞不清楚哪些东西是在硬件提供的基础上实现的,哪些东西是由纯软件实现的。我现在觉得搞清楚软硬件各自在某个功能上起到了什么作用是非常重要的)

80X86提供了多任务的硬件支持。任务是一个正在运行的程序,或者是一个等待准备运行的程序。通过中断、异常、跳转或调用,我们可以执行一个任务。

描述符表中与任务相关的描述符有两类:任务状态段(TSS)描述符和任务门。当执行权传给这任何一类描述符时,都会造成任务切换。

任务切换很像过程调用,但任务切换会保存更多的处理器信息。转移操作要求保存处理器中几乎所有寄存器的当前内容,包括标志寄存器EFLAGS和所有段寄存器。任务不可充入,任务切换不会把任何信息压入堆栈中,处理器的状态信息都被保存在内存中称为任务状态段(Task state segment)的数据结构中。

4.7.1 任务的结构和状态

任务由两部分构成:任务执行空间;任务状态段(Task state segment)

  • 任务执行空间:包括代码段、堆栈段和一个或多个数据段。任务执行空间需要为每个特权级提供一个独立的堆栈空间;
  • TSS:指定了构成任务执行空间的各个段,并且为任务状态信息提供存储空间。在多任务环境中,TSS也为任务之间的链接提供了处理方法。

在这里插入图片描述
在这里插入图片描述
对每个任务都是4GB的线性空间,因此,对每个任务都有自己的LDT以及自己的页表。也因此,每次在进行任务切换时段寄存器需要都需要保存。可参考进程中有多少个段表、多少个页表?
具体对每个任务内存是如何管理的?如何将前面的知识串起来,还是需要继续学习。

每个任务的状态的组成如上所示。即需要哪些信息才能完整的描述一个任务。
通用寄存器8个,段寄存器6个,再加上标志寄存器、EIP、CR3、LDTR。
注意前面说道的内容哪些是每个任务都有一套,哪些是只有一套的,比如GDTR和IDTR是只有一套的,是全局的;但是LDTR中的信息是每次任务切换都要进行切换的,是属于每个任务各自有一套的。

4.7.2 任务的执行

软件或处理器可以使用以下方法之一来调度执行一个任务:

  • 使用CALL指令明确的调用一个任务;
  • 使用JMP指令明确地跳转到一个任务(Linux内核使用的方式)
  • (由处理器)隐含地调用一个中断句柄处理任务;
  • 隐含地调用一个异常句柄处理任务;

所有这些调度任务执行的方法都会使用一个指向任务门或任务TSS段的选择符来确定一个任务。
当进行调度时,当前正在执行的任务的执行环境(称为任务状态或上下文信息)会被保存到它的TSS中。
如果调用者调用了被调用任务,那么调用者的TSS段选择符会被保存在被调用者的TSS中,作为返回用。80X86任务不可递归调用,即任务不能调用自己。
在这里插入图片描述
每个任务都有自己的LDT和自己的一套页表。

4.7.3 任务管理数据结构

处理器定义了以下一些支持多任务的寄存器和数据结构(注意是处理器定义的):

  • 任务状态段TSS;
  • TSS描述符;
  • 任务寄存器TR;
  • 任务门描述符;
  • 标志寄存器EFLAGS中的NT(嵌套任务标志Nested Task)标志

这些数据结构,处理器可以从一个任务切换到另一个任务。

4.7.3.1 任务状态段

用于恢复一个任务执行的处理器状态信息被保存在称为任务状态段TSS(Task state segment)的段中。32位CPU的TSS格式如图4-34。TSS段中各字段可以分成两大类:动态字段和静态字段。
在这里插入图片描述
上图的表中共104个字节。

1.动态字段。当任务切换而被挂起时,处理器会更新动态字段的内容。这些字段包括:

  • 8个通用寄存器字段
  • 6个段选择符字段
  • 标志寄存器EFLAGS字段
  • 指令指针EIP字段
  • 先前任务连接字段。含有前一个任务TSS段选择符(在调用、中断或异常激发的任务切换时更新)。该字段(通常也称为后连接字段(Back link field))允许任务使用IRET指令切换到前一个任务。

以上字段是每次任务被切换之前必须重新保存的。

2.静态字段。处理器会读取静态字段的内容,但通常不会改变它们。这些字段是在任务被创建时设置的。包括:

  • LDT段选择符字段。
  • CR3控制寄存器字段。
  • 特权级0、1和2的堆栈指针字段。
  • 调试陷阱(Debug Trap)T标志字段。字节0x64的bit0处。当设置了该位,处理器切换到该任务的操作会产生一个调试异常。
  • I/O位图基地址字段。该字段很有从TSS段开始处到I/O许可位图处的16位偏移地址。
    关于I/O位图基地址可以参考一个操作系统的实现

在这里插入图片描述
这是因为需要对TSS进行读写操作。

4.7.3.2 TSS描述符

TSS描述符格式如图4-35所示,TSS描述符只能存放在GDT中。在本书4.3.6节已经有提到过TSS段描述符。
在这里插入图片描述
类型字段TYPE中的忙标志B用于指明任务是否处于忙状态。忙状态是指当前正在执行的任务或等待执行(被挂起)的任务。B=0,不忙;B=1,忙。

当颗粒度G=0时,限长字段必须具有大于等于103(0x67)的值,即TSS段的最小长度不得小于104字节。当包含I/O许可位时,TSS段长度还要更大一些。

在这里插入图片描述

4.7.3.3 任务寄存器

任务寄存器TR(Task Register)中存放着16位的段选择符以及当前任务TSS段的整个描述符(不可见部分)。
指令LTR和STR分别用于加载和保存任务寄存器的可见部分,即TSS的段选择符。LTR指令只能被特权级0程序执行,LTR指令通常用于系统初始化期间给TR寄存器加载初值,随后在系统运行期间,TR的内容会在任务切换时自动的被改变(也就是是处理器自己在做这些事情)。

4.7.3.4 任务门描述符

任务门描述符(Task gate descriptor)提供对一个任务间接、受保护地引用。格式如图4-36所示。任务门描述符可以被存放在GDT、LDT或IDT表中。

在这里插入图片描述
在这里插入图片描述

4.7.4 任务切换

处理器可使用以下种方式之一执行任务切换操作:

  • 当前任务对GDT中的TSS描述符执行JMP或CALL指令;
  • 当前任务对GDT或LDT中的任务门描述符执行JMP或CALL指令;
  • 中断或异常向量指向IDT表中的任务门描述符;
  • 当EFLAGS中的NT标志置位时当前任务执行IRET指令;

在这里插入图片描述
在这里插入图片描述
任务切换操作示意图如下图所示:
在这里插入图片描述
首先将当前处理器中的需要保存的状态信息进行保存;然后根据选择符对新任务的状态信息进行加载。

当切换到一个新任务时,处理器会执行以下操作:
1.获得新任务的TSS段选择符(可能在JMP或CALL的操作数中、或任务门中、或当前TSS的前一任务链接字段中)
2.检查当前任务是否允许切换到新任务。
3.检查新任务的TSS段描述符是标注为存在的(P=1),并且TSS段长度有效(大于0x67)。
4.如果任务切换产生自JMP或IRET指令,处理器就会把当前任务(老任务)TSS描述符中的忙标志B复位;如果任务切换是由CALL指令、异常或中断产生,则忙标志B不同(说明在等待资源);
5.如果任务切换由IRET产生,则处理器会把临时保存的EFLAGS映像中的NT标志复位;如果任务切换由CALL、JMP指令或者异常或中断产生,则不用改动上述NT标志。
6.把当前任务的状态保存到当前任务的TSS中。
7.如果切换是由CALL指令、异常或中断产生,则处理器就会把从新任务中加载的EFLAGS中的NT标志置位。如果任务切换产生自JMP或IRET指令,就不改动新加载EFLAGS中的标志。
8.如果任务切换由CALL、JMP指令或者异常或中断产生,处理器就会设置新任务TSS描述符中的忙标志B;如果任务切换由IRET产生,则不去改动B标志。
9.使用新任务TSS的段选择符和描述符加载任务寄存器TR(包括隐藏部分)。设置CR0寄存器的TS(任务已切换(Task Switched))标志。
10.把新任务的TSS状态加载进处理器。在此期间检测到的任何错误都将出现在新任务的上下文中。
11.开始执行新任务。

对新的TSS段中的内容的修改在加载进入处理器之前吗?如第7和第8条?这个是为什么呢?

TS标志来协调处理器和浮点协处理器之间的操作。TS标志表明协处理器中的上下文内容可能与当前正在执行任务的不一致。

4.7.5 任务链

TSS的前一任务连接(Backlink)字段以及EFLAGS中的NT标志用于返回到前一个任务操作中。NT标志指出了当前执行的任务是否是嵌套在另一个任务中执行。
在这里插入图片描述
当使用CALL指令、中断或异常造成任务切换,处理器把当前TSS段的选择符复制到新任务TSS段的前一任务链接字段中,然后再EFLAGS中设置NT标志位。此时IRET会返回前一个任务。
当使用JMP指令进行任务切换时,新任务不是嵌套的,NT标志会被设置为0。即JMP指令用于不希望出现嵌套的任务切换中。

表4-10总结了任务切换期间,忙标志B(在TSS段描述符中)、NT标志、前一任务链接字段和TS标志(在CR0中的用法)。运行于任何特权级上的程序都可以修改NT标志。
在这里插入图片描述
JMP不会产生任务嵌套。
为什么IRET之后老任务忙标志B还会被设置呢?这个时候不应该被清除吗/

4.7.6 任务地址空间

任务的地址空间由任务能够访问的段构成。这些段包括代码段、数据段、堆栈段、TSS中引用的系统段以及任务代码能够访问的任何其他段。这些段都被映射到处理器的线性地址空间中,并且随后被直接地或者通过分页机制映射到处理器的物理地址空间中。

在这里插入图片描述
可以通过共享LDT或GDT中的某些段来实现不同任务之间的通讯和相互控制。

4.7.6.1 把任务映射到线性和物理地址空间

有两种方法可以把任务映射到线性地址空间和物理地址空间:

  • 所有任务共享一个线性到物理地址空间的映射。没有开启分页机制时,只有这个办法。如果开启了分页,则通过共用页目录来实现;
  • 每个任务有自己的线性地址空间,并映射到物理地址空间。每个任务都使用不同的页目录。
    在这里插入图片描述
    所谓共享的地址空间,就是说对每个任务的相同的线性地址都映射到相同的物理页面上,这样一些共享的数据就可以在不同的任务中使用,而不用改变。
    比如对GDT(全局描述符表)来说,整个内存中只有一份这个表,但是每个任务都需要可以访问。因此在不同任务的线性地址空间中,其GDTR中保存的GDT的基地址所对应的实际物理地址是相同的。即对GDT的线性基地址,具有相通的物理地址映射,这样保证了数据的共享。
    极端一点,假如说,两个任务的页表是完全相同的,则两个任务的数据是完全共享的。对任务1的某个线性地址对应的物理地址也是任务2同样的线性地址对应的物理地址。这样的方法可以实现内存共享(这部分是我自己现在的理解)
4.7.6.2 任务逻辑地址空间

为了在任务之间共享数据,可使用下列方法之一来为数据段建立共享的逻辑到物理地址空间的映射:

  • 通过使用GDT中的段描述符。
  • 通过共享的LDT。
  • 通过映射到线性地址空间公共地址区域的不同LDT中的段描述符。如果线性地址空间中的这个公共区域对每个任务都映射到物理地址空间的相同区域,那么这些段描述符就允许任务共享这些段。这样的段描述符通常称为别名段。

4.8 保护模式编程初始化

在这里插入图片描述

4.8.1 进入保护模式时的初始化操作

保护模式所需要的一些数据结构由处理器内存管理功能确定。分段机制和分页机制都需要操作系统在内存中为内存管理硬件设置所需要的数据结构。因此在处理器能够被切换到保护模式下运行之前,操作系统加载和初始化软件(bootsect.s、setup.s和head.s)必须在内存中线设置好保护模式下使用的数据结构的基本信息。包括

  • 保护模式中断描述符表IDT;
  • 全局描述符表GDT;
  • 任务状态段TSS;
  • 局部描述符表LDT;
  • 若使用分页机制,则起码需要设置一个页目录和一个页表;
  • 处理器切换到保护模式下运行的代码段;
  • 含有中断和异常处理程序的代码模块。

在能够切换到保护模式之前,软件初始化代码还必须设置以下系统寄存器:

  • 全局描述符表基地址寄存器GDTR;
  • 中断描述符表基地址寄存器IDTR;
  • 控制寄存器CR1–CR3;

在初始化了这些数据结构、代码模块和系统寄存器之后,通过设置CR0寄存器的保护模式标志PE(位0),处理器就可以切换到保护模式下运行。

4.8.1.1 保护模式系统结构表

软件初始化期间在内存中设置的保护模式系统表主要依赖于操作系统将要支持的内存管理类型:平坦的、平坦并支持分页的、分段的或者分段并支持分页的。

也就是其实硬件提供了一些规则,操作系统可以选择如何使用这些规则。硬件是规则的制定者;软件是使用者。

在这里插入图片描述

4.8.1.2 保护模式异常和中断初始化

软件初始化代码必须设置一个保护模式IDT,其中最少需要含有处理器可能产生的每个异常向量对应的门描述符。
在可以使用IDT之前,必须使用LIDT指令把IDT表基地址和长度加载到IDTR寄存器中。

4.8.1.3 分页机制初始化

分页机制由控制器CR0中的PG标志设置。当PG=0,不开启;当PG=1,开启。在设置PG时,必须先初始化以下数据结构和寄存器:

  • 软件必须在物理内存中建立至少一个页目录和一个页表。
  • 把页目录表的物理基地址加载到CR3寄存器(PBDR)中
  • 处理器处于保护模式下,如果满足所有其他限制,则PG和PE标志可以同时设置。

为保持兼容性,设置PG标志(以及PE标志)时必须遵循以下规则:

  • 设置PG标志的指令应该立即跟随一条JMP指令。
  • 设置PG标志到跳转指令JMP之间的代码必须来自对等映射(即跳转之前的线性地址于开启分页后的物理地址相同)的一个页面上。这也是容易理解的,为了防止出现执行不连续的现象。
4.8.1.4 多任务初始化

如果将要使用多任务机制,并且/或者允许改变特权级,那么软件初始化代码必须至少设置一个TSS及相应的TSS段描述符(因为特权级0、1和2的各栈段指针需要从TSS中取得)。在创建TSS描述符时不要将其标注为忙(不要设置忙标志),该标志仅由处理器在执行任务切换时设置,
在处理器切换到保护模式之后,使用LTR将TSS段描述符加载到TR寄存器,这个指令会同时把TSS段描述符标记成忙状态(B=1)。(硬件自动实现)
在这里插入图片描述

4.8.2 模式切换

为了让处理器工作在保护模式下,必须从实地址模式下进行模式切换操作。一旦进入保护模式,软件通常不会再需要回到实地址模式。为了还能运行为实地址模式编址的程序,通常在虚拟-8086模式中运行比再切换回实模式下运行更为方便。

4.8.2.1 切换到保护模式

在切换到保护模式之前,必须首先加载一些起码的系统数据结构和代码模块。即进行初始化。通过执行在CR0寄存器中设置PE标志的MOV CR0指令,可以进入保护模式。刚进入保护模式中运行时,特权级是0。为了保证程序的兼容性,切换操作步骤为:
1.禁止中断。
2.执行LGDT指令把GDT表的基地址加载进GDTR寄存器;
3.执行在控制寄存器CR0中的设置PE标志(可选同时设置PG标志)的MOV CR0指令。
4.在MOV CR0指令之后立刻执行一个远跳转JMP或远调用CALL指令。这个操作通常是远跳转到或远调用指令流中的下一条指令;(这边的JMP或CALL应该不会引起任务切换)
5.若要使用局部描述符表,则执行LLDT指令把LDT段的选择符加载到LDTR寄存器中;
6.执行LTR指令,用初始保护模式任务的段选择符或者可写内存区域的段描述符加载任务寄存器TR。这个可写内存区域用于在任务切换时存放任务的TSS信息。
7.在进入保护模式后,段寄存器仍然含有在实地址模式时的内容。第4步中的JMP或CALL指令会重置CS寄存器。其余段寄存器的内容可通过重新加载或切换到一个新任务来更新。
8.执行LIDT指令把保护模式IDT表的基地址和长度加载到IDTR寄存器中。(注意此时中断已经被禁止了,所以在执行上述指令时,不会有中断发生)
9.执行STI指令开启可屏蔽硬件中断,并且执行必要的硬件操作开启NMI中断。

在这里插入图片描述

4.8.2.2 切换回实地址模式

使用MOV CR0指令把控制寄存器CR0中的PE标志清0。重新进入实地址模式的过程应该按照如下步骤进行:
在这里插入图片描述
结合2.3.2节理解一下实模式运行。
实模式下使用的是内存最低位置的1MB字节?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值