zoukankan      html  css  js  c++  java
  • X86保护模式 八操作系统类指令

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

     

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

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

     

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

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

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

      a) 

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

      SGDT QWORD PTR DST

      其中DST48位存储器操作数   

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

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

      SIDT QWORD  PTR   DST

      Dst48位    将IDTR寄存器的内容存储到存储器单元DSTIDTR16位界限存入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

        SRC48位  

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

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

        LIDT QWORD   PTR   SRC

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

      D 装载机器状态字

        LMSW DST

        DST16位 的存储器操作数或寄存器   ,将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的程序才能改变这些寄存器的值,设置和存储控制寄存器及调试寄存器的指令都是特权指令。

  • 相关阅读:
    MySQL学习——SQL查询语句(连接查询&子查询)(三)
    MySQL学习——SQL查询语句(使用集合函数查询)(二)
    MySQL学习——SQL查询语句(一)
    MySQL学习——操作数据库(增删改查)(二)
    MySQL学习——操作数据库(增删改查)(一)
    MySQL学习——MySQL数据库概述与基础
    Python学习之——Http协议简介
    Python学习之——Socket套接字(UDP连接)
    第04组 Beta版本演示
    第04组 Beta冲刺(4/5)
  • 原文地址:https://www.cnblogs.com/dongguolei/p/7865368.html
Copyright © 2011-2022 走看看