如果操作系统不使用处理器的多任务机制,它仍然需要为栈创建至少一个TSS
当程序通过调用门改变特权级的时候,处理器执行下面的步骤切换栈,并且执行被调用的程序在新的特权级
1. 使用目标代码段的DPL从TSS中选择栈段选择子和栈指针
2. 从当前TSS读取被切换的栈段选择子和栈指针。当读取栈段选择子,栈指针或者栈段描述符的时候,任何界限违规都会造成#TS异常
3. 检测栈段描述符的类型和特权级是否正确,如果违规了,则会产生#TS异常
4. 暂时保存当前的SS和ESP寄存器的值
5. 加载新栈的段选择子和栈指针到SS和ESP寄存器
6. 把暂时被保存的SS和EIP寄存器的值压入新栈
7. 从调用者的栈复制调用门的参数数量字段指定的参数个数到新栈。如果参数数量是0,则没有参数被复制
8. 把返回指令指针(当前CS和EIP寄存器的值)压入到新栈
9. 加载新代码段的段选择子和调用门中指定的指令指针到CS和EIP寄存器,然后开始执行被调用的程序
总结:选择->读取->加载SS和ESP->压入调用者的SS和ESP->压入调用者的参数->压入返回指令指针->加载目标代码段的地址到CS和EIP中->go
调用门中的参数数量字段指定了处理器应该从调用者栈复制到被调用程序栈的数据项数量(最多31个数据项),如果数据项超过31位被复制,参数可以成为指向数据结构的指针,或者被保存的SS和EIP寄存器的内容可以用于访问旧栈中的参数,数据项被复制的size取决于调用门的size
5.8.6 从被调用的程序中返回
RET指令能用于执行近返回,同等特权级的远返回,和不同特权级的远返回. 这个指令主要用于从曾经用CALL指令调用的被调用过程中返回。它不支持从JMP指令返回,因此JMP指令不在栈上保存返回指令指针
近返回紧急转移程序控制在当前代码段内;因此,处理器紧急执行界限检查,当处理器从栈中POP返回指令指针到EIP寄存器中时,它会检查指针是否会超过当前代码段的界限
同等特权级的远返回上,处理器从栈上Pop被返回的代码段的段选择子和返回指令指针。正常环境下,这些指针应该是有效的,因为它们是通过CALL指令PUSH到栈中的。然而,