## 7.5 任务切换(Task Switching)
以下情况中,80386切换到另一个任务执行:
1、 当前任务执行了一个JMP或CALL,而操作数中指定了一个TSS描述符。
2、 当前任务执行了一个JMP或CALL,而操作数中指定了一个任务门。
3、 一个在IDT中的中断向量或异常向量导致向一个新的任务切换。
4、 当前任务执行了一条IRET指令,而且NT位设置时。
JMP, CALL, IRET, 中断和异常原先被设计用于在同一个任务内的机制,不需要任务切换。访问到何种类型的描述符还是在标志字段NT(nested taks)位可以用于区分出标标准的机制还是变种的任务切换机制。
为了引起任务切换,JMP或CALL指令可以指定一个TSS描述符或者一个任务门。两种情况下作用是相同的:80386切换到指定的任务。
当在IDT中的中断或异常向量指示了一个任务门时,中断或异常将引起任务切换。如果指示了一个IDT中的中断门或陷阱门,不发生任务切换。关于中断的更多信息,请参看第9章。
当以一个任务或一个中断子程序来引发时,中断处理程序总是将控制返回到被中断任务的子程序。如果NT位被置位,中断处理程序则是一个中断任务,IRET指令将返回到被中断的子程序。
任务切换操作将做以下的步骤:
1、 检测当前任务有权切换到指定的任务。这时数据访问规则将用于检测JMP或CALL指令。TSS描述符或者任务门的DPL字段必须小于或者等于CPL和门选择子RPL字段的最大值。中断、异常、IRET指令可以切换到任何任务,而不必管目标TSS描述符或者目标任务门的DPL字段。
2、 检测目标TSS描述符存在的,而且有一个有效的界限值。到这时,所有的错误都算是在的引发任务切换(outgoing task)的上下文中发生的。错误是可以被处理和重起的,且对于应用程序是透明的。
3、 保存当前任务的状态。处理器从任务寄存器中缓存的不可见部分来找到当前任务的基址。处理器拷贝寄存器值到当前任务TSS(EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, ES, CS, SS, DS, FS, GS, 和 标志寄存器EFLAG)。EIP字段则指向引起任务切换的指令的下一条指令。
4、 将新的任务的选择子加载到任务寄存器,将新任务的TSS描述符设置为忙。设置MSW的TS(task switched)标志位。选择子或是从指令操作数中得到,或是从任务门中得到。
5、 从新的任务的TSS中加载任务的状态,并恢复其执行。加载的寄存器是LDT寄存器,标志寄存器(EFLAG)通用寄存器EIP,EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI;段寄存器ES,CS,SS,DS,FS,和GS。还有PDBR(CR3)。所有检测到的错误将发生在新任务的上下文中。对于一个异常处理程序,看来起好似新任务的第一条指令还未执行。
注意,不管怎么样,旧任务的状态总是会被保存。如果这个任务被重新执行,它执行引起任务切换的指令的后一条指令。当任务执行时,所有寄存器的值将被恢复。
每一次任务切换都会设置MSW(machine status word)的TS(task switched)位。TS标志对于有协处理器的系统来说是很重要的。TS位指出了协处理器的状态可能和当前任务的状态不一致了。第11章进一步讨论TS位。
处理任务切换异常的处理程序(表7-1中由第4到16引起的异常)应该注意加载引起异常的选择子的操作。这样的操作可能引发第二次异常,除非异常处理程序首先检查了选择子并修定了潜在的问题。
将要执行的任务的特权级即不被引起任务切换的任务所影响,也不会被它所约束。因为每个任务的地址空间是分开的,且有不同的TSS,还有就是特权级规则可以用于防止不合法的TSS访问,但是没有哪种特权级规则需要用来去约束不同任务间的CPL。新的任务将在CS选择子的RPL字段特权级执行,这个CS是由TSS中加载的。
![](https://box.kancloud.cn/2016-03-06_56dbfdaf51be8.jpg)
- 第一章 80386介绍
- 1.1 该手册的组织结构
- 1.2 其他文献
- 第二章 编程基本模型
- 2.1 存储器组织和段
- 2.2 数据类型
- 2.3 寄存器
- 2.4 指令格式
- 2.5 操作数选择
- 2.6 中断和异常
- 第4章 系统寄存器
- 4.1 系统寄存器 (System Registers)
- 4.2 系统指令 (System Instructions)
- 第五章 内存管理
- 5.1 分段地址转换(Segment Translation)
- 5.2 分页地址转换(Page Translation)
- 5.3 混合分段和分页地址转换(Combining Segment and Page Translation)
- 第六章 内存管理
- 6.1 为什么要保护(Why Protection?)
- 6.2 80386保护机制概述(Overview of 80386 Protection Mechnaisms)
- 6.3 段级保护(Segment-Level Protection)
- 6.4 页级保护(Page-Level Protection)
- 6.5 混合分页和分段保护(Combining Page and Segment Protection)
- 第7章 多任务(Multitasking)
- 8.1 I/O 寻址(I/O Addressing)
- 7.1 任务状态段(Task State Segment)
- 7.3 任务寄存器(Task Register)
- 7.4 任务门描述符(Task Gate Descriptor)
- 7.5 任务切换(Task Switching)
- 7.6 任务链(Task Linking)
- 7.7 任务寻址空间(Task Address Space)
- 第8章 输入 输出
- 8.2 I/O 指令(I/O Instructions)
- 8.3 保护和I/O(Protection and I/O)
- 第9章 异常和中断(Exceptions and Interrupts)
- 9.1 识别中断(Identifying Interrupts)
- 9.2 允许和禁止中断(Enabling and Disabling Interrupts)
- 9.3 同时发生的中断和异常的优先级(Priority Among Simultaneous Interrupts and Exceptions)
- 9.4 中断描述符表(Interrupt Descriptor Table)
- 9.5 IDT 描述符(IDT Descriptors)
- 9.6 中断任务和中断子程序(Interrupt Tasks and Interrupt Procedures)
- 9.7 出错码(Error Code)
- 9.8 异常条件(Exception Conditions)
- 9.9 异常总结(Exception Summary)
- 9.10 出错码总结(Error Code Summary)
- 第10章 初始化(Initialization)
- 10.1 复位后处理器状态(Processor State After Reset)
- 10.2 实模式初始化(Software Initialization for Real-Address Mode)
- 10.3 切换到保护模式(Switching to Protected Mode)
- 10.4 保护模式初始化(Software Initialization for Protected Mode)
- 10.5 初始化示例
- 10.6 TLB测试
- 第十四章 80386实地址模式
- 14.1 物理地址构成
- 14.2 寄存器和指令
- 14.3 中断和异常处理
- 14.4 进入和离开实地址模式
- 14.6 实地址模式异常
- 14.7 与8086的不同
- 14.8 与80286实地址模式的不同