一.什么是TSS:
TSS全称Task State Segment,中文名任务状态段,储存在内存中,大小104个字节,结构如下:
二.TSS原本的作用:
TSS在任务(进程)切换时起着重要的作用,通过它保存CPU中各寄存器的值,实现任务的挂起和恢复。
比如说,当CPU执行A进程的时间片用完,要切换到B进程时,CPU会先把当前寄存器里的值保存到A进程的TSS里(任务寄存器TR指向当前进程的TSS),比如CS,EIP,ESP,标志寄存器等等,然后挂起A进程。执行B进程。这样,在CPU下次执行A进程的时候,就可以从其TSS中取出,CPU就知道上一次A进程执行到了什么位置,执行状态等等,这样就恢复了上次A进程的执行现场。(但是Windows和Linux并没有使用TSS进行任务切换的工作,是使用的堆栈来实现的任务(也就是线程)的切换.但是在执行调用门操作的时候,ESP和SS的值就是通过TSS来自动进行切换的.)
三.CPU如何调用TSS:
CPU中有一个TR段寄存器,存出一个段描述符,存在于GDT段描述符表中,属于系统段描述符的一种,base指向TSS表的地址,limit表示他的偏移范围.
四.我们对于TSS的调用:
1.申请内存空间,自己写一个TSS表(104字节),并为表中的寄存器赋值.
2.修改GDT表中的段描述符,让其Base指向我们自己的TSS表
3.CALL FAR 或者 JMP FAR,跳到段描述符,使用我们的TSS表.(会先自动改写TR寄存器,不需要LTR在改了.)
1)也可以通过LTR指令:修改TR寄存器的段选择子,让TR寄存器指向GDT表中我们改写的TR段描述符.(LTR是系统指令,只有在R0层,才能使用)
mov ax,4B(GDT中,自己写的段描述符)
ltr ax
*加载后TSS段描述符状态会更改(就是上图的B位),TYPE的值由1001变为1011.
*如果要读TR寄存器的值,也就是段选择子,可以用STR指令.
上述操作完成,可以一次性改写一堆寄存器,在指向TSS表的时候,我们可以使用CALL FAR 和JMP FAR指令来进行,需要注意的是二者的区别, CALL FAR后NT位为1,返回时,EIP会取Previous Task Link的值,JMP FAR后NT位为0,返回时,EIP从堆栈中取值.
原文地址:https://www.cnblogs.com/jszyx/p/12431773.html