天天看點

TSS段(轉載)

轉載自:https://blog.csdn.net/q1007729991/article/details/52650822,講的非常好,我就稍微寫點提醒自己的,大部分都是借鑒的23333(懶…)

TSS:Task State Segment

一個TSS的結構類似于下圖

typedef struct TSS {
    DWORD link; // 儲存前一個 TSS 段選擇子,使用 call 指令切換寄存器的時候由CPU填寫。
    // 這 6 個值是固定不變的!!!,用于提權,CPU 切換棧的時候用
    DWORD esp0; // 儲存 0 環棧指針
    DWORD ss0;  // 儲存 0 環棧段選擇子
    DWORD esp1; // 儲存 1 環棧指針
    DWORD ss1;  // 儲存 1 環棧段選擇子
    DWORD esp2; // 儲存 2 環棧指針
    DWORD ss2;  // 儲存 2 環棧段選擇子
    // 下面這些都是用來做切換寄存器值用的,切換寄存器的時候由CPU自動填寫。
    DWORD cr3; 
    DWORD eip;  
    DWORD eflags;
    DWORD eax;
    DWORD ecx;
    DWORD edx;
    DWORD ebx;
    DWORD esp;
    DWORD ebp;
    DWORD esi;
    DWORD edi;
    DWORD es;
    DWORD cs;
    DWORD ss;
    DWORD ds;
    DWORD fs;
    DWORD gs;
    DWORD ldt;
    // 這個暫時忽略
    DWORD io_map;
} TSS;
           

它和TRAP_FRAME很像,TSS聽名字是為了儲存任務狀态的,而不是任務切換的!!!

TSS段(轉載)

和 gdtr,idtr 這些不同的是,tr 寄存器是段寄存器,之前已經知道的段寄存器有 cs, ds, es, ss, fs, gs 。也知道段寄存器有96位,還做過實驗驗證。tr 寄存器中存放的直接就是描述了TSS段的相關資訊的一個描述符,比如TSS段的基址,大小和屬性。

TSS段(轉載)

GDT 表中可以存放多個 TSS描述符,這意味着記憶體中可以存在多份不同的TSS。總有一個 TSS 是在目前使用中的,也就是 tr 寄存器指向的那個 TSS。當使用 call/jmp + TSS段選擇子的時候,CPU做了以下幾件事情。

把目前所有寄存器(TSS結構中有的那些寄存器)的值填寫到目前 tr 段寄存器指向的 TSS 中
        把新的 TSS 段選擇子指向的段描述符加載到 tr 段寄存器中
        把新的 TSS 段中的值覆寫到目前所有寄存器(TSS結構中有的那些寄存器)中
           

說白了,它有兩個用途

  1. 儲存0~3環的SS,ESP,雖然0,1是沒用的
  2. 通過 call/jmp 指令 可以切換到tr寄存器所存的描述符所指base所指向的TSS結構

繼續閱讀