段描述符与段选择子
1、段描述符
2、段选择子
3、详解
mov fs ,0x30
30–>00110 0 00 –>rpl=0 index=6 –>GDT[6]
FS:[0]–>GDT[6].Base+0x0
段描述符属性:P位 G位
P=1段描述符才是有效的
G=0 limit的单位是字节 G=1limit的单位是4kb limit的最后补0xFFF;
段描述符属性:S位 TYPE域
1、S位
S=1 代码or数据段
A–访问位 W–是否可写 E–扩展方向
S=0系统段
A–访问位 R–可读位 C–一致位
段描述符属性:DB位 一般都为1
调用门
1、调用门执行流程
指令格式:CALL CS:EIP(EIP是废弃的)
执行步骤:
1) 根据CS的值 查GDT表,找到对应的段描述符 这个描述符是一个调用门.
2) 在调用门描述符中存储另一个代码段段的选择子.
3) 选择子指向的段 段.Base + 偏移地址 就是真正要执行的地址.
2、门描述符
————EC/8C
3、堆栈变化
发生改变的寄存器:ESP EIP CS SS
中断门
1、IDT
IDT即中断描述符表,同GDT一样,IDT也是由一系列描述符组成的,每个
描述符占8个字节。但要注意的是,IDT表中的第一个元素不是NULL。
2、IDT表的构成
IDT表可以包含3种门描述符:
任务门描述符
中断门描述符
陷阱门描述符
3、中断门描述符
————EE/8E
陷阱门
1、陷阱门描述符
————EF/8F
任务段
1、TSS的结构
TSS是一块内存 内存结构如图,大小104字节
2、TSS的作用
Intel的设计思想
操作系统的设计思想
本质:
不要把TSS与“任务切换”联系到一起
TSS的意义就在于可以同时换掉”一堆”寄存器
3、CPU如何找到TSS呢? TR段寄存器
4、(TSS Descriptor)TSS段描述符
————EB/8B
5、TR寄存器读写
1) 将TSS段描述符加载到TR寄存器
指令:LTR
说明:
用LTR指令去装载的话 仅仅是改变TR寄存器的值(96位)
并没有真正改变TSS
LTR指令只能在系统层使用
加载后TSS段描述符会状态位会发生改变
2) 读TR寄存器
指令:STR
说明:如果用STR去读的话,只读了TR的16位 也就是选择子
构造任务段
CPU通过TR段寄存器来找到TSS.如果我们想用自己的TSS段来替换原来的寄存器,就要修改TR寄存器,TR寄存器的值又是来自TSS段描述符,那么我们接下来先构造一个段描述符。
- 准备TSS所需的104字节
- TSS的赋值
- TSS段描述符
修改TR寄存器
1) 在Ring0 我们可以通过LTR指令去修改TR寄存器2) 在Ring3 我们可以通过CALL FAR 或者 JMP FAR指令来修改
用JMP去访问一个代码段的时候,改变的是CS和EIP :
JMP 0x48:0x123456 如果0x48是代码段
执行后:CS-->0x48 EIP-->0x123456
用JMP去访问一个任务段的时候:
如果0x48是TSS段描述符,先修改TR寄存器,在用TR.Base指向
的TSS中的值修改当前的寄存器
任务门
- 任务门描述符
————E5/85 - 任务门执行过程:
INT N
查IDT表,找到任务门描述符
通过任务门描述符,查GDT表,找到任务段描述符
使用TSS段中的值修改寄存器
IRETD返回