处理器在实施任务切换时的操作——《x86汇编语言:从实模式到保护模式》读书笔记39

来源:互联网 发布:互联网算法工程师 编辑:程序博客网 时间:2024/05/16 14:21

处理器在实施任务切换时的操作——《x86汇编语言:从实模式到保护模式》读书笔记39

处理器可以通过以下四种方法实施任务切换:
1. call指令或者jmp指令的操作数是GDT内的某个TSS描述符的选择子;
2. call指令或者jmp指令的操作数是GDT或者LDT内某个任务门的选择子;
3. 一个异常或者中断发生时,中断号指向IDT内的某个任务门;
4. 在EFLAGS寄存器的NT位置位的情况下,当前任务执行了一个iret指令。

对于这四种方法,首先都可以得到一个TSS描述符的选择子:
对于1,指令的操作数直接就是TSS选择子;
对于2和3,任务门里包含了TSS选择子;
对于4,当前任务的TSS的任务链接域内就是TSS选择子。
这个TSS选择子就决定了要切换到哪个任务。

在任务切换时,处理器执行以下操作:
1. 取得新任务的TSS描述符的选择子(如上文所述)。
2. 检查是否允许从当前任务切换到新任务。
(1)数据访问的特权级检查规则适用于JMP和CALL指令,当前任务的CPL和新任务段选择子(TSS描述符的选择子或者任务门的选择子)的RPL必须在数值上<=目标TSS描述符或者任务门的DPL;
(2)异常、中断(int n指令发起的中断除外)和IRET指令引起的任务切换忽略目标任务门或者TSS描述符的DPL;
(3)对于int n指令发起的中断,要检查DPL,要求在数值上,CPL<=任务门描述符的DPL;
3. 检查新任务的TSS描述符是否已经标记为有效(P=1),并且界限也有效(>=103);
4. 检查新任务是否可用。对于以CALL,JMP,异常或者中断发起的任务切换,要求B=0;对于IRET发起的任务切换,要求B=1;
5. 检查当前任务和新任务的TSS,以及所有在任务切换时用到的段描述符已经安排到系统内存中;
6. 如果任务切换是由JMP或者IRET发起的,处理器清除当前任务的B标志;如果是由CALL指令、异常或者中断发起的,当前任务的B位保持原来的状态(=1);
7. 处理器建立EFLAGS寄存器的一个临时副本。如果任务切换由IRET指令发起,则清除副本中的NT标志;如果是由CALL、JMP、异常或者中断发起的,则保持副本中NT标志不变。
8. 保存当前任务的状态到它的TSS中:所有通用寄存器、段寄存器中的段选择子、刚才那个EFLAGS的副本,以及EIP;
9. 加载新任务的EFLAGS寄存器。如果任务切换是由CALL、异常或者中断发起的,处理器把EFLAGS的NT标志置位;如果是由IRET或JMP发起的,NT位不变。
10. 如果任务切换是由CALL、JMP、异常或者中断发起的,处理器将新任务TSS描述符中的B标志置位;如果由IRET发起,B保持原来的状态(=1);
11. 用新任务的TSS选择子和TSS描述符加载TR;
12. 新任务的TSS状态数据被加载到处理器:包括LDTR寄存器、CR3、EFLAGS、EIP、通用寄存器、段选择子;
13. 与段选择子相对应的描述符在验证后也被加载;
14. 开始执行新任务。

注意:任务切换时,新任务的特权级别是由其段寄存器CS的低2位决定的,该寄存器的内容取自新任务的TSS。

最后,再次给出那个表格,因为它太重要了。

1 0