兰陵月 发表于 2017-12-7 17:04:05

X86汇编语言-从实模式到保护模式—笔记(35)-第14章 任务和特权级保护(1)

本帖最后由 兰陵月 于 2017-12-15 12:21 编辑

14.1任务的隔离和特权级保护
【14.1.1任务、任务的LDT和TSS】程序是记录在载体上的指令和数据,总是为了完成某个特定的工作。【是否可以理解为:“程序”就是我们编写的源代码经过编译之后产生的可执行文件,它只是存放在硬盘、光盘、U盘等载体上,并未被加载到内存中由处理器执行】。任务是程序正在执行的一个副本。【是否可以理解为:任务就是处理器将载体上的某个程序加载到了内存中并正在执行的运行状态】。一、LDT的相关知识为了有效地在任务之间实施隔离,处理器建议每个任务都应当具有自己的描述符表,称为局部描述符表LDT(Local Descriptor Table),并且把专属于自己的那些段放到LDT中。LDT也是用来存放描述符的。它与GDT的不同之处在于,LDT只属于某个任务。每个任务都有自己的LDT,每个任务私有的段,都应当在LDT中进行描述。LDT的第1个描述符,也就是0号槽位,也是有效的、可以使用的。GDTR寄存器追踪和访问GDT。LDTR追踪和访问LDT。在一个多任务的系统中,会有很多任务在轮流执行,正在执行的那个任务,称为当前任务(Current Task)。因为LDTR寄存器只有一个,所以,它只用于指向当前任务的LDT。每当发生任务切换时,LDTR的内容被更新,以指向新任务的LDT。和GDTR一样,LDTR包含了32位线性基地址字段和16位段界限字段,以指示当前LDT的位置和大小。在访问内存之前需要指定一个段,方法是向段寄存器的选择器传送一个段选择子,这称为“引用一个段”,比如:“mov cx,0x0008”“mov ds,cx”。我们回顾一下段选择子的构成,段选择子总共16位,其中第1、0位是RPL;第2位是TI位,如果TI=0,则表示描述符在GDT中,如果TI=1,则表示描述符在LDT中;第15~3位是描述符的索引号。在这里,“0x0008”是选择子,它的二进制表示形式为:0000_0000_0000_1000,我们可以看到,它的第1、0位RPL=00;它的第2位TI=0,表明描述符在GDT中;它的第15~3位为1,表示描述符的索引号为1(十进制)。处理器将访问GDT,从1号槽位取得描述符,并传送到段寄存器DS的描述符高速缓存器中。再看一个例子:“mov cx,0x005C”“mov ds,cx”。“ 0x005C”的二进制表示形式为:0000_0000_0101_1100,我们可以得知,它的第1、0位RPL=00;它的第2位TI=1;它的第15~3位索引号为11(十进制)。处理器执行这两条指令的时候,必然会访问当前任务的LDT(该LDT在内存中的位置由LDTR指定),从它的11号槽位取出描述符,并传送到段寄存器DS的描述符高速缓存器中去。段选择子是16位的,而且只有高13位被用作索引号来访问GDT或者LDT,所以,每个LDT所能容纳的的描述符个数为2^13,即8192个。或者换句话说,每个LDT只能定义8192个段。又因为每个描述符的长度是8字节,LDT的长度最大为64KB。二、TSS的相关知识在一个多任务的环境中,当任务切换发生时,必须保护旧任务的运行状态,或者说是保护现场,保护的内容包括通用寄存器、段寄存器、栈指针寄存器ESP、指令指针寄存器EIP、状态寄存器EFLAGS,等等。否则的话,等下次该任务又恢复执行时,一切都会变得茫然而毫无头绪。为了保存任务的状态,并在下次重新执行时恢复它们,每个任务都应当用一个额外的内存区域保存相关信息,这叫做任务状态段(Task State Segment:TSS),如图14-001。任务状态段TSS具有固定的格式,最小尺寸是104字节,图14-001中所标注的偏移量是十进制的。处理器固件能够识别TSS中的每个元素,并在任务切换的时候读取其中的信息。
    和LDT一样,处理器用TR寄存器来指向当前任务的TSS。和GDTR、LDTR一样,TR寄存器在处理器中也只有一个。当任务切换发生的时候,TR寄存器的内容也会跟着指向新任务的TSS。这个过程是这样的:首先,处理器将当前任务的现场信息保存到由TR寄存器指向的TSS;然后,再使TR寄存器指向新任务的TSS,并从新任务的TSS中恢复现场。


页: [1]
查看完整版本: X86汇编语言-从实模式到保护模式—笔记(35)-第14章 任务和特权级保护(1)