X86保护模式  八操作系统类指令

通常在操作系统代码中使用,应用程序中不应用这些指令

指令分为三种:实模式指令,任何权级下使用的指令、实模式权级0下可执行的指令和仅在保护模式下执行的指令

一  实模式和任务特权级下可执行的指令

  1.存储全局和中断描述符表寄存器指令

利用存储描述符表寄存器指令能把描述符表寄存器的内容保存到指定的存储单元。与GDT与IDT被所有任务共享不同,LDT是每个任务私有的。所以存储局部描述符表寄存器的LDTR的指令不在所列

  a)

  存储全局描述符表寄存器指令

  SGDT QWORD PTR DST

  其中DST为48位存储器操作数

  将全局描述符表寄存器GDTR的内容存储到存储单元DST。GDTR中的16位界限存入DST的低字,GDTR中的32位基地址存入DST的高双字,不影响标志位。

  b)存储中断描述符表寄存器指令

  SIDT QWORD  PTR   DST

  Dst位48位    将IDTR寄存器的内容存储到存储器单元DST。IDTR的16位界限存入DST的低字,IDTR中的32位基地址存入DST的高双字。不影响标志位。

2.存储机状态字指令

  SMSW   DST

  DST可以是16位的存储器操作数或寄存器。该指令的功能是把机器状态字存储到DST   不影响标志位

  80386  如果需要存储机器状态字   最好使用存储CR0寄存器的指令

二  实模式及权级0下可执行的指令

  下列指令涉及设置关键的寄存器,所以只能在实模式和保护模式的权级0下执行。

  在保护模式下,如果当前权级cpl不为0,将产生错误码为0的通用保护故障。

  a 清任务切换标志指令

    CLTS

    每当任务切换时,cr0中的任务切换标志TS被自动置为1,功能将ts标志清0.

    仅影响TS标志,对其他标志没有影响。

  B 暂停指令

    HLT

    使cpu暂停执行。暂停之后,只有在接受一个已经启用的中断或让系统复位,才能重新启动,不影响标志位。

  C 装载全局描述符表和中断描述符表寄存器的指令

    1.装载全局描述符表寄存器

    LGDT QWORD  PTR   SRC

    SRC为48位

    将存储器中的伪描述符装入到全局描述符表寄存器GDTR中。伪描述符src的结构如前文所述结构类型PDESC所示,低字是以字节为单位的段界限,高双字是段基地址。不影响标志位。

    2.装载中断描述符表寄存器

    LIDT QWORD   PTR   SRC

    将存储器中的伪描述符装入到中断描述符表寄存器IDTR中。低字以字节为单位的段界限,高双字是段基地址。不影响标志位

  D 装载机器状态字

    LMSW DST

    DST是16位 的存储器操作数或寄存器   ,将DST的内容装载到机器状态字。不影响标志位。

    pe位置1   便进入保护模式。

  e  控制寄存器数据传送指令

    MOV   DST,SRC

    控制寄存器和32位通用寄存器之间的数据传送 ,两个操作数可以是三个寄存器和任一32位通用寄存器,但不能同时是控制寄存器,不影响标志位

  f  调试寄存器数据传送指令

    同上,调试寄存器与32位通用寄存器之间的数据传送,可以是调试寄存器和任一32位通用寄存器,但不能同时是调试寄存器。   不影响标志位

    386中的6个调试寄存器:DR0    DR1   DRW    DR3   DR6   DR7

  g  测试寄存器数据传送指令

    同e中的指令相同,实现测试寄存器和32位通用寄存器之间的数据传送, 2个测试寄存器是TR6和TR7

三  只能在保护模式下执行的指令

  在实模式下执行,会引起非法操作码故障,向量号为6

  1.装载和存储局部描述符表寄存器指令

    a  装载局部描述符表寄存器指令

      LLDT   SRC

      操作数可以是16位通用寄存器或存储单元,将src中的内容作为指示局部描述符表LDT的选择子装入到LDTR寄存器。不影响标志位。

      SRC给定的选择子应该指示GDT中的类型为LDT的描述符。但LRC也是一个空选择子,表示暂时不使用局部描述符表LDT。

      若CPL不为0,那么执行该指令将产生出错码位0的通用保护故障。若被装载的选择子不指示GDT中的描述符,或者描述符类型不是LDT描述符,那么产生通用保护故障,错误码由该选择构成

      LDTR有两部分,指示LDT的选择子装入LDTR可见部分时,描述符中的信息也被保存到高速缓冲寄存器。

    b  存储局部描述符表寄存器指令

      SLDT  DST

      dst为16位 寄存器或存储单元,将局部描述符表寄存器LDTR的内容存储到存储单元DST中。不影响标志位

 2.装载和存储任务寄存器指令

     任务寄存器TR指示当前任务状态段TSS,随着任务的切换,TR的内容也随之改变,如果任务嵌套,那么tr的原值作为链接字保存到新任务的TSS中。但有时候需要直接地装载后者保存TR,这就需要使用装载TR指令和存储TR指令。

    a  装载任务寄存器可指令

      LTR     SRC

         SRC为16位通用寄存器或者存储器单元。将src作为指示tss描述符的选择子装载到任务寄存器TR。把TSS的选择子装入到TR的可见部分。cpu自动把选择子索引的描述符中的段基地址等信息保存到不可见的高速缓冲寄存器中。所以src表示的选择子不能为空,必须索引位于GDT中的描述符,并且描述符类型必须是可用TSS,该加载的TSS被处理器自动标为"忙",不影响标志位。

      如果cpl不为0,会产生错误码为0的通用保护故障。

      如果被加载的选择子不指示GDT中的可用TSS描述符,那么产生通用保护故障,错误码由选择构成。

    b  存储任务寄存器指令

    STR    DST

      将tr所示的指示当前任务TSS描述符的选择子存储到DST  ,不影响标志位

 3.调整申请特权级指令

  ARPL  OPRD1,OPRD2

  OPRD1可以是16位通用寄存器或存储的单元,oprd2是16位通用寄存器。将两个操作数看作两个选择子,用oprd2的申请特权级rpl去检查oprd1的rpl。

选择子oprd1和oprd2的rpl分别由他们的最低2个位规定。如果oprd1的rpl小于oprd2的rpl,那么零标志ZF被置1,并把op2的rpl值赋予op1的rpl (使两个数的最低2位相等),否则,零标志zf被清0.op1和op2都可以为空选择子。影响ZF标志。

4.装载存取权指令

  LAR  OP1,OP2

  OP1 16位或32位通用寄存器,op2是16位通用寄存器或存储单元,也可以是32位通用寄存器或存储单元,两个操作数尺寸需要一致,把op2看作选择子,32位中仅适用低16位。

  如果op2所指示的描述符满足下面的条件,zf被置1  并将描述符内的属性字段装入op1,否则zf清0,op1保持不变。

  a  在描述符表的范围内

  b  是存储段描述符或系统段描述符或任务门描述符或调用门描述符

  c  cpl和op2的rpl都不大于dpl

  在满足条件的情况下,装入到op1的由op2所指示的描述符中的属性字段是指描述符的高4字节和00fxff00h相与的结果,其中x表示第16位到第19位无定义。如果使用16位操作数,那么只有高4字节中的低字被装入到op1,即装入到op1的属性字段不包括g位和avl位等,只影响zf标志位

5.装载段界限指令

  LSL OP1,OP2

  OP1可以是16位或32位通用寄存器    op2可以是16位或32位的寄存器或存储单元

  将op2看成选择子  ,如果op2所指示的描述符满足如下条件,那么zf置1,并把描述符内的界限字段装入op1,否则zf清0,op1不变

  a  在描述符表的范围内

  b  是存储段描述符或系统段描述符,而非门描述符

  c  cpl和op2的rpl都不大于dpl

  满足条件时,装入到op1的有op2所指示的描述符中的界限字段以字节为单位,如果描述符中的界限字段以4k字节为单位g=1,那么装入到op1时左移12位,空出的低位全部填写成1.如果指令使用16位操作数,那么只有段界限的低16位被装入到op1,影响zf标志位

6.读写检验指令

  利用读检验指令和写检验指令可以分别检查在当前权级上指定的段能否读或写,从而避免引起不必要的异常

  a  读检验

  VERR  oprd

  op可以是16位或32位通用寄存器或存储器单元     将op内容作为一个选择子   使用32位中的低16位,判断当前特权级上该选择子指示的段是否刻度,如果该选择子指示一个合法的存储段描述符,并且在当前权级上刻度所描述的段,那么ZF被置为1,否则被清0,只影响zf标志位。

  b  写检验

  VERW  OPRD

  同上,检验选择子指向的段是否可写。

实例:显示关键寄存器内容的实例   实例八

为了更好地说明操作系统类指令的使用,下面给出一个显示80386关键寄存器内容的实例。该实例的逻辑功能是,显示系统中GDTR、IDTR、LDTR和TR等关键寄存器的当前内容。实例八的源程序清单如下:
;名称:ASM8.ASM
;功能:显示关键寄存器内容及说明操作系统类指令的使用
;编译:TASM ASM8.ASM
;连接:TLINK ASM8.OBJ
;----------------------------------------------------------------------------
INCLUDE 386SCD.INC
;----------------------------------------------------------------------------
GDTSeg SEGMENT PARA USE16 ;全局描述符表数据段(16位)
;----------------------------------------------------------------------------
GDT LABEL BYTE
;空描述符
DUMMY Desc <>
;规范段描述符及选择子
Normal Desc <0ffffh,,,ATDW,,>
Normal_Sel = Normal-GDT
;----------------------------------------------------------------------------
EFFGDT LABEL BYTE
;临时任务代码段描述符及选择子
TempCode Desc <0ffffh,TempCodeSeg,,ATCE,,>
TempCode_Sel = TempCode-GDT
;缓冲区段描述符及选择子
Buffer Desc <BufferLen-1,BufferSeg,,ATDW,,>
Buffer_Sel = Buffer-GDT
;测试描述符1及选择子
Test1 Desc <1111h,,,92h,87h,>
Test1_Sel = Test1-GDT
TestR_Sel = Test1-GDT+RPL3
;测试描述符2及选择子
Test2 Desc <2222h,,,82h,17h,>
Test2_Sel = Test1-GDT
;----------------------------------------------------------------------------
GDNum = ($-EFFGDT)/(SIZE Desc) ;需特殊处理的描述符数
GDTLen = $-GDT ;全局描述符表长度
;----------------------------------------------------------------------------
GDTSeg ENDS ;全局描述符表段定义结束
;----------------------------------------------------------------------------
BufferSeg SEGMENT PARA USE16 ;缓冲区数据段
;----------------------------------------------------------------------------
GDTR_V PDesc <> ;存放GDTR
IDTR_V PDesc <> ;存放IDTR
;----------------------------------------------------------------------------
MSW_V DW 0 ;存放机器状态字
LDTR_V DW 0 ;存放LDTR选择子
TR_V DW 0 ;存放TR选择子
CR0_V DD 0 ;存放控制寄存器CR0
CR3_V DD 0 ;存放控制寄存器CR3
DR7_V DD 0 ;存放调试寄存器DR7
Test_RPL DW 0
;----------------------------------------------------------------------------
Test1_SLD DD 0 ;演示用变量
Test1_ARD DD 0
Test1_SLW DW 0
Test1_ARW DW 0
Test1_RF DW 0
Test1_WF DW 0
;----------------------------------------------------------------------------
Test2_SLD DD 0 ;演示用变量
Test2_ARD DD 0
Test2_SLW DW 0
Test2_ARW DW 0
Test2_RF DW 0
Test2_WF DW 0
;----------------------------------------------------------------------------
BufferLen = $
BufferSeg ENDS
;----------------------------------------------------------------------------
TempCodeSeg SEGMENT PARA USE16 ;临时代码段
ASSUME CS:TempCodeSeg,DS:BufferSeg
;----------------------------------------------------------------------------
Virtual PROC FAR
mov ax,Buffer_Sel
mov ds,ax
mov eax,cr0 ;存储CR0
mov CR0_V,eax
mov eax,cr3 ;存储CR3
mov CR3_V,eax
mov eax,DR7 ;存储DR7
mov DR7_V,eax
str TR_V ;存储TR
sldt LDTR_V ;存储LDTR
mov Test_RPL,Test1_Sel
mov ax,TestR_Sel
arpl Test_RPL,ax ;说明调整申请特权及指令
mov bx,0
mov ax,Test1_Sel
Lab1: mov edx,0
mov cx,0
lsl edx,eax ;说明装载段界限指令
lsl cx,ax
mov Test1_SLD[bx],edx
mov Test1_SLW[bx],cx
mov edx,0
mov cx,0
lar edx,eax ;说明装载存取权指令
lar cx,ax
mov Test1_ARD[bx],edx
mov Test1_ARW[bx],cx
mov Test1_RF[bx],0
verr ax ;说明读检验指令
jnz Lab2
mov Test1_RF[bx],1
Lab2: mov Test1_WF[bx],0
verw ax ;说明写检验指令
jnz Lab3
mov Test1_WF[bx],1
Lab3: add bx,16
mov ax,Test2_Sel
cmp bx,32
jb Lab1
;准备返回实方式
mov ax,Normal_Sel
mov ds,ax
mov eax,cr0
and al,11111110b
mov cr0,eax ;返回实方式
JUMP16 <SEG Real>,<OFFSET Real>
Virtual ENDP
;----------------------------------------------------------------------------
TempCodeSeg ENDS
;----------------------------------------------------------------------------
RCodeSeg SEGMENT PARA USE16
ASSUME CS:RCodeSeg,DS:BufferSeg
;----------------------------------------------------------------------------
VGDTR PDesc <GDTLen-1,>
;----------------------------------------------------------------------------
Start PROC
mov ax,BufferSeg
mov ds,ax
sgdt GDTR_V
sidt IDTR_V
smsw MSW_V
;准备转入保护方式
push cs
pop ds
cld
call InitGDT
mov bx,OFFSET VGDTR
lgdt [bx]
cli
mov eax,cr0
or al,1
;转入保护方式
mov cr0,eax
JUMP16 <TempCode_Sel>,<OFFSET Virtual>
Real: ;回到实方式
sti
;为了简单,略去了显示相关变量内容的部分代码
mov ax,4c00h
int 21h
Start ENDP
;----------------------------------------------------------------------------
InitGDT PROC
push ds
mov ax,GDTSeg
mov ds,ax
mov cx,GDNum
mov si,OFFSET EFFGDT
InitG: mov ax,[si].BaseL
movzx eax,ax
shl eax,4
shld edx,eax,16
mov WORD PTR [si].BaseL,ax
mov BYTE PTR [si].BaseM,dl
mov BYTE PTR [si].BaseH,dh
add si,SIZE Desc
loop InitG
pop ds
mov bx,16
mov ax,GDTSeg
mul bx
mov WORD PTR VGDTR.Base,ax
mov WORD PTR VGDTR.Base+2,dx
ret
InitGDT ENDP
;----------------------------------------------------------------------------
RCodeSeg ENDS
END Start

五  特权指令

保护方式下,只有当权级cpl=0,才可执行的指令,如果cpl不等于0,引起通用保护异常

装入GDTR      IDTR    LDTR    TR   和MSW的指令都是特权指令,而存储上述寄存器的指令不是特权指令,这表示保护模式下任何程序可以获得这些寄存器的值,但是只有特权级0的程序才能改变这些寄存器的值,设置和存储控制寄存器及调试寄存器的指令都是特权指令。

X86保护模式 八操作系统类指令的更多相关文章

  1. x86 保护模式 十 分页管理机制

    x86   保护模式  十  分页管理机制 8.386开始支持分页管理机制 段机制实现虚拟地址到线性地址的转换,分页机制实现线性地址到物理地址的转换.如果不启用分页,那么线性就是物理地址 一  分页管 ...

  2. x86保护模式-七中断和异常

    x86保护模式-七中断和异常 386相比较之前的cpu   增强了中断处理能力   并且引入了 异常概念 一 80386的中断和异常 为了支持多任务和虚拟存储器等功能,386把外部中断称为中断     ...

  3. x86保护模式 实模式与保护模式切换实例

    x86保护模式     实模式与保护模式切换实例 实例一 逻辑功能   以十六进制数的形式显示从内存地址110000h开始的256个字节的值    实现步骤: 1  切换保护方式的准备 2. 切换到保 ...

  4. x86保护模式 任务状态段和控制门

    x86保护模式    任务状态段和控制门 每个任务都有一个任务状态段TSS     用于保存任务的有关信息     在任务内权变和任务切换时  需要用到这些信息    任务内权变的转移和任务切换  一 ...

  5. x86保护模式-六 控制转移

    控制转移可以分为两大类  :同一任务内的控制转移    和   任务间的控制转移(任务切换) 同一个任务内的控制转移可以分为段内转移 .特权级不变的段间转移和特权级改变的段间转移 段内转移与实模式相同 ...

  6. x86保护模式 二 分段管理机制

    分段管理机制 段选择子和偏移地址的二维虚拟地址转换为一维的线性地址 一  段定义和虚拟地址到线性地址的转换 三个参数定义段:段基地址    段界限  和段属性    同时也是段描述符的结构 段基地址为 ...

  7. x86保护模式 控制寄存器和系统地址寄存器

    控制寄存器和系统地址寄存器 控制寄存器    crx cr0   指示cpu工作方式的控制位  包含启用和禁止分页管理机制的控制位  包含控制浮点协处理器操作的控制位   注意必须为0的位 cr2和c ...

  8. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16

    一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...

  9. 进入保护模式(二)——《x86汇编语言:从实模式到保护模式》读书笔记14

    首先来段题外话:之前我发现我贴出的代码都没有行号,给讲解带来不便.所以从现在起,我要给代码加上行号.我写博客用的这个插入代码的插件,确实不支持自动插入行号.我真的没有找到什么好方法,无奈之下,只能按照 ...

随机推荐

  1. Git中文件属性的变化,被认为是文件有改动

    问题描述: 1.  从公司的git服务器上, 下载最新的代码(zip格式), 解压缩出来, 2.  过一段时间, 去执行git pull代码, 出现如下情况: $ git pull Updating ...

  2. 【javascript类库】zepto和jquery的md5加密插件

    [javascript类库]zepto和jquery的md5加密插件 相信很多人对jQuery并不陌生,这款封装良好的插件被很多开发者使用. zepto可以说是jQuery在移动端的替代产品,它比jQ ...

  3. JavaScript_10_错误

    Try...catch... throw <!DOCTYPE html> <html> <head> <title></title> < ...

  4. Codeforces 724 G Xor-matic Number of the Graph 线性基+DFS

    G. Xor-matic Number of the Graph http://codeforces.com/problemset/problem/724/G 题意:给你一张无向图.定义一个无序三元组 ...

  5. 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest J Computer Network1 (缩点+最远点对)

    题意:在连通图中,求一条边使得加入这条边以后的消除的桥尽量多. 在同一个边双连通分量内加边肯定不会消除桥的, 求边双连通分量以后缩点,把桥当成边,实际上是要选一条最长的链. 缩点以后会形成一颗树,一定 ...

  6. UVA 12325 Zombie'sTreasureChest 宝箱 (分类枚举)

    看上去非常像背包的问题,但是体积太大了. 线性规划的知识,枚举附近点就行了,优先选性价比高的, 宝物有两种体积为S0,价值V0,体积S1,价值V1. 枚举分以下几种: 1:枚举拿宝物1的数量,然后尽量 ...

  7. coreData-Fetching Managed Objects

    https://developer.apple.com/library/content/documentation/DataManagement/Conceptual/CoreDataSnippets ...

  8. 剑指offer46 求1+2+...+n 以及& &&区别

    参考代码: class Solution { public: int Sum_Solution(int n) { int result = n; result && (result + ...

  9. npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\James\package.json'

    在运行如下命令时, 遇到了问题: npm install --registry=https://registry.npm.taobao.org npm run dev 错误提示: 解决办法: 生成一个 ...

  10. Python——序列封包与序列解包

    一.序列封包与序列解包 把多个值赋给一个变量时,Python会自动的把多个值封装成元组,称为序列封包. 把一个序列(列表.元组.字符串等)直接赋给多个变量,此时会把序列中的各个元素依次赋值给每个变量, ...