目录
- 保护模式简述
- 分段管理机制
- 控制寄存器与系统地址寄存器
- 任务状态段和控制门
- 控制转移
- 386中断和异常
- 操作系统类指令
- 输入输出保护
- 分页管理机制
- 虚拟8086
- 80486寄存器
- 80486对调试的支持
- Pentium 程序设计基础
保护模式简述
线性地址由大小可变的存储块构成,这样的存储块称为段
通过描述符表和描述符,实现分段管理机制
任务当前特权级,标记CPL
(Current Privilege Level)
SS
寄存器中的选择子的RPL
字段,就是CPL- 当前代码段选择子的 RPL 字段,就是CPL
描述符特权级,标记DPL
(Descriptor Privilege Level)
- 门的
DPL
规定了访问门的最外层特权级,只有相同级或更高内级可以访问门。假如门DPL=3,就只能0/1/2能使用该门
选择子请求特权级,标记位RPL
(Requested Privilege Level)
RPL<=CS(CPL) && RPL<=DPL
因为能执行代码,RPL肯定<=CPL,所以只需要满足RPL<=DPL就行
局部变量 cs == ss
全局变量 cs == ds
分段管理机制
段是实现虚拟地址到线性地址转换机制的基础,段由如下三个参数进行定义:
- 段基地址(Base Address)
- 段界限(Limit)
- 段属性(Attributes)
基地址和界限定义了段所映射的线性地址的范围
描述符可分为如下三类
- 存储段描述符
- 系统段描述符
- 门描述符(控制描述符)
存储段是存放可由程序直接进行访问的代码和数据的段
-
P
位称为存在(Present)位。P=1表示描述符对地址转换是有效的,P=0表示描述符对地址转换无效实验验证:
如果修改DS段P位为0,不可读
如果修改EX段P位为0,可读
-
DPL
表示描述符特权级(Descriptor Privilege Level) -
DT
位说明描述符的类型,DT=1
代表存储段 -
TYPE
-
G位就是段界限粒度(Granularity)位。G=0表示界限粒度为字节,G=1表示界限粒度是4K字节
-
D位是一个很特殊的位
- 在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小
- D=1表示默认情况下指令使用32位地址及32位或8位操作数,这样的代码段也称为32位代码段
- D=0表示默认情况下使用16位地址及16位或8位的操作数,这样的代码段也称为16位代码段
- 向低扩展数据段的描述符中,D位决定段的上部边界
- D=1表示段的上部界限为4G;
- D=0表示段的上部界限为64K
- 在描述由SS寄存器寻址的段描述符中,D位决定隐式的堆栈访问指令(如PUSH和POP指令)使用何种堆栈指针寄存器
- D=1表示使用32位堆栈指针寄存器ESP
- D=0表示使用16位堆栈指针寄存器SP
- 在描述可执行段的描述符中,D位决定了指令使用的地址及操作数所默认的大小
段描述符结构
DESCRIPTOR STRUC
LIIMITL DW 0 ;段界限低16位
BASEL DW 0 ;基地址低16位
BASEM DB 0 ;基地址中间8位
ATTRIBUTES DW 0 ;段属性(含段界限的高4位)
BASEH DB 0 ;基地址高8位
DESCRIPTOR ENDS
全局描述符和局部描述符
- 全局描述符表
GDT
(Global Descriptor Table) - 局部描述符表
LDT
(Local Descriptor Table) - 中断描述符表
IDT
(Interrupt Descriptor Table)
段选择子
- 在保护方式下,虚拟地址空间(相当于逻辑地址空间)中存储单元的地址有段选择子和段内偏移两部分组成
- 段选择子长16位
- 段选择子的高13位是描述符索引(Index)。描述符索引是指描述符在描述符表中的序号
TI=0
在GDT
中读取描述符:TI=1
在LDT
中读取描述符- 选择子的最低两位是请求特权级
RPL
(Requested Privilege Level),用于特权检查- 假设虚拟地址是
0010:12345678H
= 0000000000010 000 : 12345678H - 代表0环GDT中第2个描述符,假设描述符基址为:87654321H
- 那么线性地址为:12345678H + 87654321H = 99999999H
- 假设虚拟地址是
控制寄存器与系统地址寄存器
80386有四个32位的控制寄存器,分别命名为CR0
、CR1
、CR2
和CR3
- CR1保留
- CR0包含指示处理器工作方式的控制位,包含启用和禁用分页管理机制的控制位,包含控制浮点协处理器操作的控制位
- CR2及CR3由分页管理机制使用
控制寄存器CR0
中的位0用PE标记,位31用PG标记
- PE控制分段管理机制。
PE=0
实方式;PE=1
保护方式。 - PG控制分页管理机制。
PG=0
禁用分页;PG=1
启用分页。
控制寄存器CR2
和CR3
由分页管理机制使用
- CR2用于发生页异常时报告出错信息
- CR3用于保存页目录表的起始物理地址
GDTR
长48位,其中高32位含基地址,低16位含界限,GDTR
为GDT
这一特殊的系统段提供一个伪描述符
IDTR
长48位,其中高32位含基地址,低16位含界限
LDTR
局部描述符表寄存器规定当前任务使用的局部描述符表LDT
,LDTR
类似于段寄存器,LDTR寄存器包含当前任务的LDT的选择子,选择子中的T1位必须是0
TR
任务状态段寄存器包含指示描述当前任务的任务状态段的描述符选择子,从而规定了当前任务的状态段
任务状态段和控制门
两种系统段描述符
- 任务状态段
TSS
和局部描述符表LDT
段 DT=1
表示存储段,DT=0
表示系统段TYPE
- LDT段描述符描述任务的局部描述符表段,LDT 段描述符必须安排在全局描述符表中才有效
- 任务状态段
TSS
用于保存任务的各种状态信息,任务状态段描述符描述某个任务状态段,TSS
描述符规定了任务状态段的基地址和任务状态段的大小,在任务切换或执行LTR
指令时,要装载TR
寄存器
门描述符
GATE STRUC ;门结构类型定义
OFFSETL DW 0 ;32位偏移的低16位
SELECTOR DW 0 ;选择子
DCOUNT DB 0 ;双字计数字段
GTYPE DB 0 ;类型
OFFSETH DW 0 ;32位偏移的高16位
GATE ENDS
门描述符又可分为
- 调用门:调用门描述某个子程序的入口,调用门内的选择子必须指向代码段描述符,调用门内的偏移是对应代码段内的偏移,利用段间调用指令
CALL
,通过调用门可实现任务内从外层特权级变换到内层特权级- 双字计数字段:主程序通过堆栈把参数给子程序,利用调用门特权级和堆栈的改变,需要将外层堆栈中的参数复制到内层堆栈。双字计数字段就是记录要复制的双字参数的数量
- 任务门:任务门指示任务,任务门内的选择子必须指向
GDT
中的任务状态段TSS
描述符,门中的偏移无意义。任务的入口点保存在TSS
中。利用段间转移指令JMP
和段间调用指令CALL
,通过任务门可实现任务切换 - 中断门和陷阱门:中断门和陷阱门描述中断/异常处理程序的入口点。中断门和陷阱门内的选择子必须指向代码段描述符,门内的偏移就是对应代码段的入口点偏移。中断门和陷阱门只有在中断描述符表
IDT
中才有效
TSS
任务状态段(Task State Segment)是保存一个任务重要信息的特殊段,任务状态段寄存器TR
的含有当前任务的任务状态段描述符的选择子和当前任务状态段的段基地址和段界限
TSS
的基本格式有104字节组成,可分为链接字段区域、内存堆栈指针区域、地址映射寄存器区域、寄存器保存区域和其它字段等五个区域
;任务状态段TSS结构类型的定义
TASKSS STRUC
TRLINK DW ?,0 ;链接字
TRESP0 DD ? ;0级堆栈指针
TRSS0 DW ?,0
TRESP1 DD ? ;1级堆栈指针
TRSS1 DW ?,0
TRESP2 DD ? ;2级堆栈指针
TRSS2 DW ?,0
TRCR3 DD ? ;CR3
TREIP DD ? ;EIP
TREFLAG DW ?,? ;EFLAGS
TREAX DD ? ;EAX
TRECX DD ? ;ECX
TREDX DD ? ;EDX
TREBX DD ? ;EBX
TRESP DD ? ;ESP
TREBP DD ? ;EBP
TRESI DD ? ;ESI
TREDI DD ? ;EDI
TRES DW ?,0 ;ES
TRCS DW ?,0 ;CS
TRSS DW ?,0 ;SS
TRDS DW ?,0 ;DS
TRFS DW ?,0 ;FS
TRGS DW ?,0 ;GS
TRLDT DW ?,0 ;LDT
TRFLAG DW 0 ;TSS的特别属性字
TRIOMAP DW $ + 2 ;指向1/0许可位图区的指针
TASKSS ENDS
当TSS
对应的任务正在执行时,保存区域是未定义的,在当前任务被切换出时,这些寄存器的当前值就保存在该区域,当下次切换回原任务时,再从保存区域恢复出这些寄存器的值,从而使处理器恢复成该任务换出前的状态,最终使任务能够恢复执行
一个任务可能具有四个堆栈,对应四个特权级。TSS
的内层堆栈指针区域中有三个堆栈指针。当发生向内层转移时,则把适当的堆栈指针装入到SS
及ESP
寄存器以变换到内层的堆栈,外层堆栈的指针保存在内层堆栈中
虚拟地址到线性地址的映射由GDT
和LDT
确定,与任务相关的部分由LDT
通过LDTR
确定。任务的虚拟地址到物理空间的映射由LDTR
和CR3
确定,任务切换,地址映射关系也切换
链接字段安排在TSS
内偏移0开始的双字中,链接时低16位保存前一任务的TSS
描述符的选择子。如果当前的任务由段间调用指令CALL
或者中断/异常而激活,那么链接字段保存被挂起任务的TSS
的选择子,标志寄存器EFLAG
中的NT
位被置1,使链接字段有效。在返回时,由于NT位为1,中断返回指令IRET
将使得控制沿着链接字段所指恢复到链上的前一个任务
控制转移
控制转移基本上可分为两大类:
- 同一任务内的控制转移
- 任务间的控制转移(任务切换)
同一任务内的控制转移又分为:
- 段内转移
- 特权级不变的段间转移
- 特权级变换的段间转移
任务内无特权级变换的转移,段间转移:
-
指令
JMP
、CALL
和RET
都具有段间转移的功能,指令INT
和IRET
总是段间转移 -
在保护方式下,段间转移的目标位置由选择子和偏移构成的地址表示,常把它称为目标地址指针,在32位代码段中,偏移为32位,16位代码中,偏移为16位
任务内不同特权级的变换转移
CPL
CALL/RET的RPL
CALL/RET的RPL指向的DPL
CALL/RET的RPL指向的RPL
CALL/RET的RPL指向的RPL指向的DPL
DPL规定了RPL的最大值
如何判断CPL:TSS中有各环的SS,不管特权集如何切换,只要找到当前栈对应选择子就可以确定CPL
-
通过调用门的转移
-
门的
DPL
规定了访问门的最外层特权级,只有相同级或更高内级可以访问门。假如门DPL=3,就只能0/1/2能使用该门门的选择子RPL
<=
门的DPL。假如门DPL=0,RPL只能为0 -
通过调用门向内层CALL/JMP,执行前检测
CPL<=DPL(目标门) && RPL(门内选择子)<=DPL(门内选择子指向的段)
,假如。CPL=3,DPL(门)只能等于3,RPL(门内选择子)=0/1/2/3, -
调用时,偏移会被丢弃
-
CALL
指令在最后把目标代码段的指针装入CS
和EIP
之前,要把原CS
和EIP
,即返回地址保存到堆栈。如变换特权级,那么返回地址保存在内层堆栈中
-
-
堆栈切换
-
切换后,首先压外层
外层SS
,外层ESP
,参数(和外层顺序一致)
,外层CS
,外层EIP
-
CALL
通过调用门向内层转移,特权级发生变换,堆栈段也要切到内层 -
特权级转行到内层,特权级使用
TSS
中的堆栈指针对SS
及ESP
寄存器进行初始化,建一个空栈 -
建立内层堆栈后,把外层堆栈的指针
SS
及ESP
寄存器的值压入内层堆栈,向返回时外层堆栈可恢复,然后复制参数,最后调用的返回地址被压入堆栈
-
-
向外层返回
RET
指令返回,先弹出外层EIP,外层CS,删除参数列表,弹出外层ESP,外层SSRET
指令先从堆栈弹出返回地址。如果返回地址的选择子的RPL
规定相对于CPL
更外层的级,那么就引起向外层返回- 返回地址选择子(
CS
)的RPL
决定返回后的CPL
任务切换
CALL/JMP,任务门/任务门状态段,中断、异常/IRET都可切换任务
TSS切换任务
- 执行
JMP/CALL 选择子
指令,选择子
指向的是一个TSS
,发生任务切换。切换入口就是TSS
中的CS
和EIP
任务门切换任务
- 任务门内的选择子指示某个任务的
TSS
描述符。JMP/CALL GATE
进行切换
切换条件
RPL<=DPL
386中断和异常
80386把外部中断称为中断
,把内部中断称为异常
中断
80386有两根引脚INTR
和NMI
接受外部中断请求信号。
INTR
接受可屏蔽中断请求。NMI
接受不可屏蔽中断请求
在80386中,标志寄存器EFLAGS
中的IF
标志决定是否屏蔽可屏蔽中断请求
处理器不屏蔽来自NMI
的中断请求,不可屏蔽中断所对应的中断向量号固定为2
NMI
处理程序应以IRET
指令结束
异常
根据引起异常的程序是否可被恢复和恢复点不同,把异常进一步分类为故障(Fault)、陷阱(Tap)和中止(Abort)
- 故障是在引起异常的指令之前,把异常情况通知给系统的一种异常。故障可以排除,跳转处理程序前保存断点
CS
、EIP
,处理程序排除故障后,IRET
返回源程序继续执行 - 陷阱是在引起异常的指令之后,把异常情况通知给系统的一种异常。陷阱可以排除,所保存的断点
CS
及EIP
的值指向引起陷阱的指令的下一条要执行指令 - 中止是在系统出现严重情况时,通知系统的一种异常。中止不可以排除
- 优先级:把优先级最高的中断或异常通知系统,其他优先级较低的异常被废弃,而优先级较低的中断则保持悬挂
中断门或陷阱门的转移
该过程由硬件自动进行
转移总结
任务切换途径
伴随着任务切换,特权级当然可能发生变换。只要任务切换发生,这种特权级的变换取决于目标任务,而与当前特权级无关。
任务内特权集变换途径
任务内相同特权级转移的途径
操作系统类指令
操作系统类指令也可分为三种:
- 只在实模式可执行
- 任何特权级下、实模式且特权级0下可执行
- 保护模式下可执行
PE=0可执行
SGDT DST ;把全局描述符表寄存器`GDTR`的内容存储到存储单元`DST`
SIDT DST ;把中断描述符表寄存器`IDTR`的内容存储到存储单元`DST`
SMSW DST ;把CR0的低16位存储到`DST`
SGDT读取GDT
#include <stdio.h> int main() { unsigned char buff[6] = {0}; __asm { sgdt buff } // 段基址,段界限 printf("%X,%X\n", *((unsigned int *)&(buff[2])), *((unsigned int*)&(buff[0]))); }
PE=0 && CRL=0 下可执行
CLTS ;把`TS`标志清0
HLT ;使处理机暂停执行,暂停之后的系统,只有在接受一个已经启用的中断,或者让系统复位,才能重新启动
LGDT SRC ;把SRC中的伪描述符装入到全局描述符表寄存器`GDTR`
LIDT SRC ;把SRC中的为描述符装入到中断描述符表寄存器`IDTR`
LMSW SRC ;将`SRC`装入CR0的低16位
PE=1下执行
LLDT SRC ;把`SRC`中的内容作为指示局部描述符表`LDT`的选择子装入到`LDTR`
SLDT DST ;把指向当前任务`LDT`的选择子存储到`DST`
LTR SRC ;将`SRC`装载到任务寄存器`TR`
STR DST ;把`TR`所含的选择子存储到`DST
ARPL OPRD1,OPRD2 ;if OPRD1.RPL<OPRD2,RPL then ZF=1 OPRD2.RPL=OPRD1.RPL else ZF=0
输入输出保护
IOPL
规定了可以执行所有与I/O
相关的指令和访问I/O
空间中所有地址的最外层特权级
I/O
许可位图规定了I/O
空间中的哪些地址可以由在任何特权级执行的程序所访问
IO
敏感指令
I/O
许可位图
I/O
许可位图由二进制位串组成
如果位串中的m位为0,那么对应的I/O
地址m可以由在任何特权级执行的程序访问
一条I/O
指令最多可涉及四个I/O
地址,如下指令读取I/O
端口71H~74H内的四个字节至EAX
IN EAX,71H
只有这多个I/O
地址所对应的I/O
位图中的位都为0时,该I/O
指令才能正常执行
当前任务使用的I/O
许可位图存储在当前任务TSS
中低端的64K字节内
I/O
访问许可检查细节
不会
分页管理机制
2 9 9 12
分页机制
10 10 12
分页机制
存储器分页管理机制
CR0
中PG=1
,分页机制生效
页的大小固定为4K字节
线性地址的低12位就是物理地址的低12位
线性地址高20位到物理地址高20位的转换就完成转换
线性地址到物理地址的转换
映射表结构
- 页映射表的第一级称为页目录表,每个表项为4字节长,包含对应第二级表所在物理地址空间页的页码
- 页映射表的第二级称为页表,每个表项为4字节长,包含对应物理地址空间页的页码
- 控制寄存器CR3指定页目录表
表项格式
最高20位(位12至位31)包含物理地址空间页的页码,也就是物理地址的高20位。低12位包含页的属性
表项的最低位是存在属性位,记作P。P位表示该表项是否有效。P=1
表项有效
页目录表或页表的表项格式:
线性地址到物理地址的转换
CR3
的高20
位指定页目录表- 线性地址的高10位(即位22至位31)为页目录表索引,找到页表项
- 线性地址的中间10位(即位12至位21)作为页表索引,找到物理地址
- 物理地址高20位和线性地址的低12连起来就是32位物理地址
页共享
部分相同的线性地址空间的映射信息相同,具体表现为部分页表相同或页表内的部分表项的页码相同
页级保护
分页机制只区分两种特权级。特权级0、1和2统称为系统特权级,特权级3称为用户特权级
表项的位1是读/写属性位,记作R/W
,R/W
位指示该表项所指定的页是否可读、写或执行
表项的位2是用户/系统属性位,记作U/S
。U/S
位指示该表项所指定的页是否是用户级页
U/S 权限位,0用户,1超级用户
R/W 读写位,0不可读写,可读写
组合页保护属性
页目录表权限和页表权限&(与)计算,才能得出最终权限
对虚拟存储器支持
P=1
,表示表项指定的页存在于物理存储器中,并且表项的高20位是物理页的页码;P=0
,表示该线性地址空间中的页所对应的物理地址空间中的页不在物理存储器中
表项的位5是访问属性位,记作A,A=1
表示已访问过对应的物理页。处理器永不清除A位
表项的位6是写标志位,记作D,D=1
表示已写过对应的物理页
页异常
出现下列情况之一就会引起页异常:
- 涉及的页目录表内的表项或者页表内的表项中的
P=0
,也即涉及的页不在内存; - 发现试图违反页保护属性的规定而对页进行访问
错误码
U
位表示引起故障程序的特权级,U=1
表示用户特权级(特权级3),U=0
表示系统特权级(特权级0、1和2);W
位表示访问类型,W=0
表示读/执行,W=1
表示写;P
位表示异常类型,P=0
表示页不存在故障,P=1
表示保护故障。
虚拟8086
EFLAGS中VM=1,进入虚拟8086
80486寄存器
寄存器
标准寄存器
新增了一个对齐检查标志AC
。如果AC置1,那么当出现地址不对齐情形时,引起地址对齐异常。但在特权级0、1和2运行时,忽略AC
位的设置,在CR0
中的AM
位为1时也忽略AC位的设置
控制寄存器CR0
新增用于控制片上超高速缓存工作方式的CD
位和NW
位;对齐屏蔽位AM
;页面写保护位WP
;数字异常位NE
新设的数字异常位NE
控制通过哪种方式报告未屏蔽的浮点部件出错故障。
NE=0
采用外部中断方式报告。当浮点部件出错时,导致中断向量号为0DH
的外部中断。NE=1
,通过引起浮点部件出错故障报告,对应中断向量号为10H
。
新设的对齐屏蔽位AM
控制标志寄存器EFLAGS
中的对齐检查标志AC
是否有效。
AM=0
,忽略AC
位。这是系统复位时的缺省状态AM=1
,考虑AC
位,这时才可能引起地址对齐异常。
新设的页面写保护位WP
控制系统级程序写访问只读页面。80386允许系统特权级(0级、1级和2级)程序写访问只读页面
WP=0
,保持与80386兼容,这是系统复位时的缺省状态。WP=1
,任何特权级程序向只读页面写访问,都将引起页故障。
新设的片上超高速缓存控制位CD
控制是否允许超高速缓存填充。
CD=0
,允许片上超高速缓存填充。CD=1
,禁止片上超高速缓存填充。
新设的片上超高速缓存直写方式控制位NW
控制是否采用直写方式。
NW=1
,采用直写方式和允许使无效,这是系统复位时的缺省状态。NW=0
,禁止直写方式及使无效。
控制寄存器CR3
CR3
的低12位中定义了2个新的控制位PCD
和PWT
调试寄存器
80486象80386一样含有6个调试寄存器,它们分别是DR0
、DR1
、DR2
、DR3
、DR6
和DR7
指令
字节交换指令BSWAP
BSWAP OPRD
BSWAP EAX ;设EAX=11223344H,执行后EAX=44332211H
交换对应关系是:第0字节与第3字节交换,第1字节与第2字节交换
交换加指令XADD
XADD OPRD1,OPRD2
XADD AL,AH ;设AX=1122H,执行后AX=2233H
交换加指令XADD
的功能是交换操作数OPRD1和OPRD2的内容,并把两个操作数相加结果送到操作数OPRD1中
当在XADD
指令前加LOCK
前缀时,能方便地实现多处理器场合的信号量操作
比较交换指令CMPXCHG
CMPXCHG OPRD1,OPRD2
其中操作数OPRD1可以是8位、16位或32位通用寄存器或者存储单元;操作数OPRD2只能是通用寄存器,并且尺寸必须与OPRD1相一致
比较交换指令的功能是把对应尺寸的累加器(EAX
、AX
、AL
)与操作数OPRD1比较,如果相等,把操作数OPRD2的内容送操作数OPRD1,并置零标志ZF。如果不等,把操作数OPRD1的内容送累加器,并清零标志ZF
使超高速缓存无效指令INVD
INVD
该指令使片上超高速缓存无效,也即清洗片上超高速缓存。该指令也产生一个特殊的总线周期,它可以用于使外部(二级)超高速缓存无效
写回并使超高速缓存无效指令WBINVD
WBINVD
该指令使片上超高速缓存无效,也即清洗片上超高速缓存,但在清洗前把片上超高速缓存中更改的内容写回主存
该指令是特权指令。只有在实方式和保护方式的特权级0下,才可执行该指令
使TLB项无效指令INVLPG
在启用分页机制的情况下,分页部件利用页目录表和页表把线性地址转换成物理地址。为了加快转换速度,80386和80486片上都有转换后援缓冲器TLB
。TLB
含32个项,用于存放当前最常使用的物理页的页码
INVLPG OPRD
其中操作数OPRD
必须是存储器操作数。该指令的功能是,如果存储器操作数OPRD
能通过TLB
中的某项转换成物理地址,那么使TLB
内对应项无效
该指令是特权指令。只有在实方式和保护方式的特权级0下,才可执行该指令。只有在特殊情况下才使用该指令,强制更新某些TLB
项
高速缓存
超高速缓存命中是指欲访问的存储单元地址作为有效标记部分出现在超高速缓存中。如果是读命中,那么直接从片上超高速缓存中读出,从而大大提高速度。如果读未命中,那么通常会把该存储单元所在行填入超高速缓存。如果写命中超高速缓存,那么80486通常(采用直写方式时)不仅向超高速缓存相应单元写,同时也向主存储器相应单元写。如果写未命中,那么直接写入主存储器相应单元,不影响超高速缓存。
片上超高速缓存的工作方式由控制寄存器CR0
中的CD
位和NW
位控制。其中,CD
位允许和禁止填充片上超高速缓存,NW
位控制直写和使无效
直写(Write-Through):写缓存的同时,直接写入到主存中
使无效(Invalidate):当主存中的数据被修改时,缓存中对应的数据可能被标记为无效,这样在下一次对该数据的访问时,将强制从主存中重新加载最新的数据
80486对调试的支持
断点地址寄存器DR0
、DR1
、DR2
和DR3
,调试状态寄存器DR6
和调试控制寄存器DR7
。这些断点寄存器都是32位寄存器
只有在实方式或特权级0执行的程序才能设置断点和进行断点处理
断点地址寄存器
断点地址寄存器用于保存断点处的线性地址,也即指示断点位置。处理器具有4个断点地址寄存器DR0
、DR1
、DR2
和DR3
,所以可以同时支持4个这样的硬
断点
不论是否启用分页机制,断点地址寄存器内保存的总是线性地址
调试控制寄存器
调试寄存器DR7
也称为调试控制寄存器
断点类型说明字段RWE
DR7
有4个RWE
字段,依次分别对应4个断点。RWEi
字段说明DRi
寄存器所指示断点的类型
断点长度说明字段
DR7
有4个LEN
字段,依次分别对应4个断点。LENi
字段说明DRi
寄存器所指示断点的长度(范围)
全局和局部断点允许位
DR7
有4个Gi
和Li
,分别对应4个断点。Gi
和Li
控制DRi
所指示的断点i在断条件满足时,是否引起断点异常。Gi
和Li
分别称为全局断点允许位和局部断点允许位。在任务切换时,处理器清各位,所以Li
位只支持一个任务范围内的断点。任务切换并不影响Gi
位,所以Gi
支持系统内各任务的断点
精确数据访问断点相符位
DR7
还有GE
位和LE
位,用于指示是否要求数据访问断点精确相符
全局调试寄存器访问检测位
DR7
的位13是调试寄存器访问检测位GD
。在GD=1
的情况下,即使在实方式或保护方式的特权级0时,访问任何调试寄存器都会引起向量号为1的调试故障
调试状态寄存器
调试寄存器DR6
也称为调试状态寄存器。异常1处理程序可根据DR6
的有关位,确定是数据访问断点、指令执行断点、单步或其他原因
DR6
内的各指示位为1时所表示的意义如下:
Bi=1(i=0,1,2,3)
表示由DRi
所指示的断点引起指令执行调试故障或进入数据访问调试陷阱。BD=1
表示在GD
置位的情况下访问调试寄存器,从而引起调试故障。在进入异常1处理程序时,自动清除GD位。BS=1
表示由于单步原因进入调试陷阱。当标志寄存器EFLAGS
中的单步标志TF
置位时,一般每执行完一条指令后就进入异常1处理程序,这就是单步。BT=1
表示刚切换到任务状态段TSS
中的调试陷耕标志T置位的任务。任务状态段TSS
内安排了一个调试陷阱标志T,从图10.14可见,该标志T是任务状态段TSS
内偏移64H处的字的最低位。在任务切换时,如果进入任务的T位为1,那么通常在任务切换完成之后,新任务的第一条指令执行之前进入调试陷阱,也即进入异常1处理程序。这也称为任务切换自陷。
调试故障和调试陷阱的区别
调试异常分为调试故障
和调试陷阱
两类
数据访问断点、单步和任务切换自陷属于调试陷阱。调试陷阱是在执行引起异常的指令之后发生,进入调试陷阱时,保存在堆栈中的返回地址指向引起陷阱的指令的下一条要执行指令
调试故障是在引起异常的指令之前发生,进入调试故障时,堆栈中的返回地址指向引起故障的指令。标志寄存器EFLAGS
中的重启动标志RF
能控制是否产生调试故障
Pentium 程序设计基础
标志寄存器
EFLAGS新增三个标志
虚拟中断标志VIF
占用标志寄存器的位19。当允许虚拟8086方式扩充或者允许保护方式虚拟中断时,VIF是中断标志的虚拟映象。当禁止虚拟8086方式扩充和禁止保护方式虚拟中断时,VIF
被强制为0。
虚拟中断挂起标志VIP
占用标志寄存器的位20。当允许虚拟8086方式扩充或者允许保护方式虚拟中断时,VIP指示虚拟中断是否挂起。当禁止虚拟8086方式扩充和禁止保护方式虚拟中断时,VIP
被强制为0。
标识标志ID占用标志寄存器的位21。如果可以设置或清除该标志,那么表示处理器支持CPUID
指令。利用该指令可获得处理器类型等信息
控制寄存器
CR4
是Pentium新增的控制寄存器
- 位2是读时间标记计数器指令
RDTSC
使用控制位TSD
。当TSD
为0时,可在任一特权级上执行读时间标记计数器指令RDTSC
。当TSD
为1时,只有在当前特权级为0时,可执行指令RDTSC
,否则将导致出错码为0的通用保护异常。RESET
后,TSD
为0,任一特权级执行的程序都可使用指令RDTSC
,读取时间标记计数器。 - 位3是调试扩充控制位
DE
。当DE
为0时,禁止调试扩充,也即不支持I/O
断点。当DE
为1时,允许调试扩充,也即支持I/O
断点。RESET
后,DE为
0,禁止调试扩充,这样Pentium就保持80486原有调试功能。 - 位0是虚拟8086方式扩充控制位
VME
。当VME
为0时,禁止虚拟8086方式扩充。 - 位1是保护方式虚拟中断控制位
PVI
。当PVI
为0时,禁止保护方式虚拟中断 - 位4是页面大小扩充控制位
PSE
。当PSE
为0时,禁止页面大小扩充。 - 位6是机器检查异常控制位
MCE
。当MCE
为0时,禁止机器检查异常。
调试寄存器
Pentium所支持的调试功能扩充是指支持I/O
断点。80486调试控制寄存器DR7
中的各断点类型说明字段RWEi
尽管是2位,但该字段取值10
的情况被保留。在允许调试扩充时,Pentium调试控制寄存器DR7
中的各断点类型说明字段RWEi
,可以取值10
,所表示的断点条件是I/O
端口读或者写。在允许调试扩充时,表11.2所列出的断点类型扩充为表11.4所列的断点类型。对应的断点地址寄存器内存放的是扩展成32位的I/O
端口地址。
控制寄存器CR4
中的DE
位决定是否允许调试功能扩充。当DE
为1时,允许调试功能扩充
指令
8字节比较交换指令CMPXCHG8B
CMPXCHG8B OPRD
其中操作数OPRD是64位存储器操作数。该指令的功能是把EDX:EAX
内的64位值与存储器操作数OPRD
相比较,如果相等,把ECX:EBX
内的64位值存入存储器操作数OPRD,如果不等,把存储器操作数OPRD内的64位值装入EDX:EAX
如果EDX:EAX
的值与存储器操作数OPRD的值相等,那么置ZF
,否则清ZF
。该指令不影响其他标志
处理器特征识别指令CPUID
CPUID
利用该指令能够方便地获得包括处理器类型在内的若干处理器特征信息
读时间标记计数器指令RDTSC
Pentium含有一个64位的时间标记计数器。该计数器随每一时钟周期递增。在RESET
后,该计数器被清0
RDTSC
该指令把时间标记计数器的高32位复制到EDX
,把低32位复制到EAX
。
控制寄存器CR4
的TSD
位限制该指令的使用。当TSD
为0时,可在任一特权级上执行RDTSC
指令,当TSD
为1时,只有当特权级为0时,可执行RDTSC
指令,否则将导致出错码为0的通用保护异常。
读模型专用寄存器指令RDMSR
RDMSR
该指令把由ECX
寄存器指定的模型专用寄存器的内容送到EDX:EAX
,EDX
含高32位,EAX
含低32位。如果所指定的模型寄存器不足64位,那么在EDX:EAX
中的对应位未定义。
写模型专用寄存器指令WRMSR
WRMSR
该指令把EDX:EAX
的内容送到由ECX
寄存器指定的模型专用寄存器,EDX
送到高32位,EAX
送到低32位
处理器的识别
CPUID执行上述指令后,EAX
含有CPU说明信息,EDX
含有特征标志字
片上高速缓存
为了适应多处理器环境的需要,对于数据超高速缓存,采用一种称为MESI
的协议,保持超高速缓存数据一致;对于指令超高速缓存,则采用MESI
协议的子集SI
来保持一致
片上超高速缓存及其工作方式的控制
每个超高速缓存都使用物理地址来访问,并且每个超高速缓存都有自己的TLB
将线性地址转换为物理地址
每一行有用于支持MESI
协议的两位相关联,可表示4种状态:M状态(Modified)、E状态(Exclusive)、S状态(Shared)和I状态(Invalid)
每一行还有用于记录最近最少使用情况的LRU
位
指令超高速缓存无需回写,所以每一行有用于支持SI协议的一位相关联,可表示S和I这2种状态
每一行也有用于记录最近最少使用情况的LRU
位相关联控制寄存器CR0
中的CD
位和NW
位可控制片上超高速缓存的工作方式
CD=0
和NW=0
能使片上超高速缓存发挥最高性能。把CD
和NW
置1能禁止超高速缓存,但为了完全禁止超高速缓存,在把CD
和NW
置1后,还应该清洗超高速缓存。在RESET
后,CD=1
和NW=1
。