32位CPU寄存器简介以及TSS和TR

CPU的指令一般都是通过寄存器来实现的。 


其中有一个寄存器叫做EIP(Instruction Pointer,指令寄存器),程序的执行就是靠EIP的不断增加来完成的(跳转的话,EIP就变成了跳转到的地址)。在Windows系统下,进程并不拥有EIP,那么只有进程,一个程序就无法运行。而拥有这些寄存器的是线程,所以说进程是静态的。一个CPU下只有一个EIP,也就是说同一时刻只能有一个线程可以运行,那么所说的多线程又是什么呢?事实上同一时刻也只有一个线程在运行,每个线程运行一段时间后,它会把它拥有的EIP等寄存器让出来,其它线程占有这些寄存器后,继续运行。 


为了实现不同的线程之间的转换,CPU要求操作系统维护一份固定格式的数据(该数据存在于内存中),这份数据叫做Task-State Segment(TSS),在这份数据结构里,维护着线程的EAX,EIP,DS(Data Segment)等寄存器的内容。 


EAX—EDX可称为数据寄存器,你除了直接访问外,还可分别对其高十六位和低十六位进行访问。它们的低十六位就是把它们前边儿的E去掉,即EAX的低十六位就是AX。而且它们的低十六位又可以分别进行八位访问,也就是说,AX还可以再进行分解,即AX还可分为AH(高八位)AL(低八位)。 


在32位程序中,32位以内的函数返回值都通过eax寄存器来传递——这是__stdcall和__ccall的调用约定形成的结果。Win32API函数(wsprintf使用__cdecl调用规则,其余所有API函数都是用__stdcall调用规则)默认是是用eax返回值。高级语言特性+编译器,通常将函数的返回值放在EAX中(单一返回值直接放EAX,如果多个返回值,则EAX中存放指针)。
 00000000 00000000 00000000 00000000
│               EAX                    │
                  │       AX           │
                  │   AH   │    AL     │
 

而CPU还有一个寄存器叫做Task Register(TR),该寄存器指向当前正在执行的线程的TSS。而线程切换事实上就是TR指向不同的TSS,这样CPU就会自动保存当前的EAX,EBX的信息到相应的TSS中,并将新的线程的信息加载到寄存器。


32位CPU的寄存器包括

4个数据寄存器 : 

    EAX  (Accumulator) 

    EBX  (Base Register) 

    ECX  (Count Register)  

    EDX  (Data Register)

2个变址和指针寄存器(Index Register) :

    ESI   (Source Index Register)

    EDI   (Destination Index Register)

1个指令指针寄存器 :

    EIP    (Instruction Pointer)

2个指针寄存器(Pointer Register) :

    ESP   (Stack Pointer Register) 

    EBP   (Base Pointer Register)

6个段寄存器(Segment Register) 

    CS    (Code Segment Register)

    DS    (Data Segment Register)

    SS    (Stack Segment Register)

    ES    (Extra Segment Register)

    FS    (Extra Segment Register)

    GS    (Extra Segment Register)

1个标志寄存器 :

    EFlags 

原文地址:https://www.cnblogs.com/mumuliang/p/1873493.html