AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > 汇编语言

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

51自学网 http://www.51zixue.net
 

<四>显示关键寄存器内容的实例(实例八)

    为了更好地说明操作系统类指令的使用,下面给出一个显示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-GDTTestR_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   <>                        ;存放GDTRIDTR_V          PDesc   <>                        ;存放IDTR;----------------------------------------------------------------------------MSW_V           DW      0                         ;存放机器状态字LDTR_V          DW      0                         ;存放LDTR选择子TR_V            DW      0                         ;存放TR选择子CR0_V           DD      0                         ;存放控制寄存器CR0CR3_V           DD      0                         ;存放控制寄存器CR3DR7_V           DD      0                         ;存放调试寄存器DR7Test_RPL        DW      0;----------------------------------------------------------------------------Test1_SLD       DD      0                         ;演示用变量Test1_ARD       DD      0Test1_SLW       DW      0Test1_ARW       DW      0Test1_RF        DW      0Test1_WF        DW      0;----------------------------------------------------------------------------Test2_SLD       DD      0                         ;演示用变量Test2_ARD       DD      0Test2_SLW       DW      0Test2_ARW       DW      0Test2_RF        DW      0Test2_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_SelLab1:           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],1Lab2:           mov     Test1_WF[bx],0                verw    ax                        ;说明写检验指令                jnz     Lab3                mov     Test1_WF[bx],1Lab3:           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     21hStart           ENDP;----------------------------------------------------------------------------InitGDT         PROC                push    ds                mov     ax,GDTSeg                mov     ds,ax                mov     cx,GDNum                mov     si,OFFSET EFFGDTInitG:          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                retInitGDT         ENDP;----------------------------------------------------------------------------RCodeSeg        ENDS                END     Start

<五>特权指令

    特权指令是指保护方式下只有当前特权级CPL=0时,才可执行的指令。如果CPL不等于0而执行它们,那么会引起通用保护异常。从上面介绍的操作系统类指令可归纳出如下表所示的80386特权指令。这些特权指令在构成完善的保护机制方面起了重要的作用。




指      令功      能指      令功      能
CLTS清除CR0中的TS位LTR装入TR寄存器
HLT停机MOV CRn,reg装入控制寄存器
LGDT装入GDTR寄存器MOV reg,CRn保存控制寄存器
LIDT装入IDTR寄存器MOV DRn,reg装入调试寄存器
LLDT装入LDTR寄存器MOV reg,DRn保存调试寄存器
LMSW装入MSW寄存器(CR0的低16位)

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

 
 

上一篇:虚拟设备驱动程序初步  下一篇:实模式和任何特权级下可执行的指令