WEB开发网
开发学院软件开发汇编语言 演示异常处理之实例七 阅读

演示异常处理之实例七

 2009-02-16 09:36:51 来源:WEB开发网   
核心提示:下面给出一个用于模拟异常和演示异常处理的实例,该实例的逻辑功能是,演示异常处理之实例七,在屏幕上显示一条提示用户以按键方式选择异常类型的字符,然后模拟指定的异常, 结束演示,转临时代码段,该实例演示内容包括:除法出错故障处理、溢出陷阱处理、段不存在故障处理、堆栈段出错处理和通用保护故障处理;还有作为一个独立任务方式出现

下面给出一个用于模拟异常和演示异常处理的实例。该实例的逻辑功能是,在屏幕上显示一条提示用户以按键方式选择异常类型的字符,然后模拟指定的异常。该实例演示内容包括:除法出错故障处理、溢出陷阱处理、段不存在故障处理、堆栈段出错处理和通用保护故障处理;还有作为一个独立任务方式出现的陷阱处理程序。

1.源程序组织和清单
  为了演示以独立任务方式出现的陷阱处理程序,实例含有两个任务:演示任务和读键盘任务。实例由如下几部分组成:

(1)全局描述符表GDT和中断描述符表IDT;
(2)读键盘任务局部描述符表、任务状态段、堆栈段和代码段等;
(3)演示任务的局部描述符表、任务状态段、堆栈段、代码段和数据段等;
(4)作为演示任务一部分的有关陷阱处理和故障处理程序的代码段;
(5)作为演示任务一部分的显示出错码过程的代码段;
(6)实模式下执行的启动和结束程序代码段和数据段。
  在切换到保护模式后,就进入临时代码段。为了简单,演示任务不发生特权级变换。演示步骤如下:

(1)从临时代码段转移到演示代码段。

(2)做演示准备。把演示任务的LDT选择子装入LDTR,并填入TSS,装载任务寄存器TR,建立演示任务堆栈,设置其它数据段寄存器。

(3)接收要模拟的异常类型号。通过软中断指令INT调用读键盘任务完成该步骤。读键盘任务只有在接收到指定的字符后才结束。接收的字符是0、4、B、C和D。

按接收的字符模拟异常。即根据键入的字符,执行有关程序片段。在这些片段中,有意安排了能引起有关故障或陷阱的指令。

结束演示,转临时代码段,返回DOS。

程序清单如下:

名称:ASM7.ASM
功能:模拟异常和演示异常处理
编译:TASM ASM7.ASM
连接:TLINK ASM7.OBJ
----------------------------------------------------------------------------
INCLUDE     386SCD.INC
----------------------------------------------------------------------------
GDTSeg     SEGMENT PARA USE16        全局描述符表数据段(16位)
----------------------------------------------------------------------------
        全局描述符表GDT
GDT       LABEL  BYTE
        空描述符
DUMMY      Desc  <>
        规范段描述符及选择子
Normal     Desc  <0ffffh,,,ATDW,,>
Normal_Sel   =    Normal-GDT
        视频缓冲区段描述符(DPL=3)及选择子
VideoBuf    Desc  <0ffffh,8000h,0bh,ATDW,,>
VideoBuf_Sel  =    VideoBuf-GDT
----------------------------------------------------------------------------
EFFGDT     LABEL  BYTE
        临时代码段描述符及选择子
TempCode    Desc  <0ffffh,TempCodeSeg,,ATCE,,>
TempCode_Sel  =    TempCode-GDT
        演示代码段描述符及选择子
DemoCode    Desc  
DemoCode_Sel  =    DemoCode-GDT
        演示任务局部描述符表段描述符及选择子
DemoLDT     Desc  
DemoLDT_Sel   =    DemoLDT-GDT
        演示任务TSS段描述符及选择子
DemoTSS     Desc  
DemoTSS_Sel   =    DemoTSS-GDT
        缓冲数据段描述符及选择子
XBuffer     Desc  
XBuffer_Sel   =    XBuffer-GDT
        读键盘任务局部描述符表段描述符及选择子
GKeyLDT     Desc  
GKeyLDT_Sel   =    GKeyLDT-GDT
        读键盘任务TSS段描述符及选择子
GKeyTSS     Desc  
GKeyTSS_Sel   =    GKeyTSS-GDT
        显示陷阱处理程序代码段描述符及选择子
EchoCode    Desc  
EchoCode_Sel  =    EchoCode-GDT
        显示出错码过程代码段描述符及选择子
SubCode     Desc  
SubCode_Sel   =    SubCode-GDT
        其它中断或异常处理程序代码段描述符及选择子
Other      Desc  
Other_Sel    =    Other-GDT
----------------------------------------------------------------------------
GDTLen     =    $-GDT           全局描述符表长度
GDNum      =    ($-EFFGDT)/(SIZE Desc)  需处理基地址的描述符个数
----------------------------------------------------------------------------
GDTSeg     ENDS               全局描述符表段定义结束
----------------------------------------------------------------------------
IDTSeg     SEGMENT PARA USE16        中断描述符表数据段(16位)
----------------------------------------------------------------------------
IDT       LABEL  BYTE           中断描述符表
        0号陷阱门描述符(对应除法出错故障)
        Gate  
        从1--3的3个陷阱门描述符
        REPT  3
        Gate  
        ENDM
        4号陷阱门描述符(对应溢出陷阱)
        Gate  
        从5--0ah的的6个陷阱门描述符
        REPT  6
        Gate  
        ENDM
        0bh号陷阱门描述符(对应段不存在故障)
        Gate  
        0ch号陷阱门描述符(对应堆栈段故障)
        Gate  
        0dh号陷阱门描述符(对应通用保护故障)
        Gate  
        从0eh--0edh的240个陷阱门描述符
        REPT  240
        Gate  
        ENDM
        对应0feh号陷阱门描述符(对应显示中断处理程序)
        Gate  
        0ffh号任务门描述符(对应读键盘中断处理任务)
        Gate  <,GKeyTSS_Sel,,ATTaskGate,>
----------------------------------------------------------------------------
IDTLen     =    $-IDT
----------------------------------------------------------------------------
IDTSeg     ENDS               中断描述符表段定义结束
----------------------------------------------------------------------------
读键盘任务局部描述符表段
----------------------------------------------------------------------------
GKeyLDTSeg   SEGMENT PARA USE16
----------------------------------------------------------------------------
GLDT      LABEL  BYTE
        代码段描述符及选择子
GKeyCode    Desc  <0ffffh,GKeyCodeSeg,,ATCE,,>
GKeyCode_Sel  =    GKeyCode-GLDT+TIL
        堆栈段描述符及选择子
GKeyStack    Desc  
GKeyStack_Sel  =    GKeyStack-GLDT+TIL
----------------------------------------------------------------------------
GKeyLDNum    =    ($-GLDT)/(SIZE Desc)   需初始化基地址的描述符个数
GKeyLDTLen   =    $             局部描述符表段长度
----------------------------------------------------------------------------
GKeyLDTSeg   ENDS
----------------------------------------------------------------------------
读键盘任务TSS段
----------------------------------------------------------------------------
GKeyTSSSeg   SEGMENT PARA USE16
        DD   0             链接字
        DD   ?             0级堆栈指针
        DW   ?,?
        DD   ?             1级堆栈指针
        DW   ?,?
        DD   ?             2级堆栈指针
        DW   ?,?
        DD   0             CR3
        DW   GKeyBegin,0        EIP
        DD   0             EFLAGS
        DD   0             EAX
        DD   0             ECX
        DD   0             EDX
        DD   0             EBX
        DW   GKeyStackLen,0      ESP
        DD   0             EBP
        DD   0             ESI
        DD   0             EDI
        DW   Normal_Sel,0       ES
        DW   GKeyCode_Sel,0      CS
        DW   GKeyStack_Sel,0      SS
        DW   Normal_Sel,0       DS
        DW   Normal_Sel,0       FS
        DW   Normal_Sel,0       GS
        DW   GKeyLDT_Sel,0       LDTR
        DW   0             调试陷阱标志
        DW   $+2            指向I/O许可位图的偏移
        DB   0ffh           I/O许可位图结束字节
GKeyTSSLen   =    $
GKeyTSSSeg   ENDS
----------------------------------------------------------------------------
读键盘任务堆栈段
----------------------------------------------------------------------------
GKeyStackSeg  SEGMENT PARA USE16
GKeyStackLen  =    1024
        DB   GKeyStackLen DUP(0)
GKeyStackSeg  ENDS
----------------------------------------------------------------------------
读键盘任务代码段
----------------------------------------------------------------------------
GKeyCodeSeg   SEGMENT PARA USE16
        ASSUME CS:GKeyCodeSeg,DS:RDataSeg,ES:BufferSeg
----------------------------------------------------------------------------
GKeyBegin    PROC  FAR
        push  ds
        push  es
        push  fs
        push  gs
        mov   ax,Normal_Sel
        mov   ss,ax           准备转实方式
        mov   eax,cr0
        and   al,11111110b
        mov   cr0,eax          转实方式
        JUMP16 ,
GetKey:     mov   ax,RDataSeg        实方式
        mov   ds,ax
        mov   ebp,esp          恢复实方式部分现场
        lss   sp,DWORD PTR SPVar
        lidt  QWORD PTR NORVIDTR
        sti
        mov   dx,OFFSET Mess
        mov   ah,9
        int   21h            显示提示信息
GetKey1:    mov   ah,0
        int   16h            读键盘
        cmp   al,'0'
        jz   GetKey2
        cmp   al,'4'
        jz   GetKey2
        and   al,11011111b       小写转大写
        cmp   al,'B'
        jb   GetKey1
        cmp   al,'D'
        ja   GetKey1          只有[0,4,b,c,d]有效
GetKey2:    mov   dl,al
        mov   ah,2
        int   21h            显示所按字符
        mov   ax,BufferSeg
        mov   es,ax
        mov   BYTE PTR es:KeyASCII,dl  保存到缓冲数据段
        cli                准备返回保护方式
        lidt  QWORD PTR VIDTR
        mov   eax,cr0
        or   al,1
        mov   cr0,eax
        JUMP16 ,
GetKeyV:    mov   ax,GKeyStack_Sel     又进入保护方式
        mov   ss,ax
        mov   esp,ebp
        pop   gs
        pop   fs
        pop   es
        pop   ds
        iretd
        jmp   GKeyBegin
GKeyBegin    ENDP
----------------------------------------------------------------------------
GKeyCodeLen   =    $
GKeyCodeSeg   ENDS
----------------------------------------------------------------------------
其它中断或异常处理程序的代码段
----------------------------------------------------------------------------
OtherCodeSeg  SEGMENT PARA USE16
        ASSUME CS:OtherCodeSeg
----------------------------------------------------------------------------
OtherBegin   PROC  FAR
        mov   si,OFFSET MessOther
        int   0feh           显示提示信息
        mov   WORD PTR es:[0],ax
        jmp   $             进入无限循环
OtherBegin   ENDP
----------------------------------------------------------------------------
OtherCodeLen  =    $
OtherCodeSeg  ENDS
----------------------------------------------------------------------------
除法出错故障处理程序代码段
----------------------------------------------------------------------------
DivCodeSeg   SEGMENT PARA USE16
        ASSUME CS:DivCodeSeg
----------------------------------------------------------------------------
DivBegin    PROC  FAR
        mov   si,OFFSET Mess0
        mov   di,0
        int   0feh           显示提示信息
        shr   ax,1           处理模拟的除法错误
        iretd               返回
DivBegin    ENDP
----------------------------------------------------------------------------
DivCodeLen   =    $
DivCodeSeg   ENDS
----------------------------------------------------------------------------
溢出陷阱处理程序代码段
----------------------------------------------------------------------------
OFCodeSeg    SEGMENT PARA USE16
        ASSUME CS:OFCodeSeg
----------------------------------------------------------------------------
OFBegin     PROC  FAR
        mov   si,OFFSET Mess4
        mov   di,0
        int   0feh           显示提示信息
        iretd               返回
OFBegin     ENDP
----------------------------------------------------------------------------
OFCodeLen    =    $
OFCodeSeg    ENDS
----------------------------------------------------------------------------
段不存在故障处理程序代码段
----------------------------------------------------------------------------
SNPCodeSeg   SEGMENT PARA USE16
        ASSUME CS:SNPCodeSeg
----------------------------------------------------------------------------
SNPBegin    PROC  FAR
        mov   si,OFFSET MessB
        mov   di,0
        int   0feh           显示提示信息
        pop   eax            弹出出错代码
        CALL16 SubCode_Sel,SubBegin   显示出错代码
        pop   eax
        add   eax,2           按模拟的引起段不存在指令
        push  eax            调整返回地址
        iretd
SNPBegin    ENDP
----------------------------------------------------------------------------
SNPCodeLen   =    $
SNPCodeSeg   ENDS
----------------------------------------------------------------------------
堆栈段故障处理程序代码段
----------------------------------------------------------------------------
SSECodeSeg   SEGMENT PARA USE16
        ASSUME CS:SSECodeSeg
----------------------------------------------------------------------------
SSEBegin    PROC  FAR
        mov   si,OFFSET MessC
        mov   di,0
        int   0feh           显示提示信息
        pop   eax            弹出出错代码
        CALL16 SubCode_Sel,SubBegin   显示出错代码
        pop   eax
        add   eax,4           按模拟的引起堆栈段错误的
        push  eax            指令调整返回地址
        iretd
SSEBegin    ENDP
----------------------------------------------------------------------------
SSECodeLen   =    $
SSECodeSeg   ENDS

1 2  下一页

Tags:演示 异常 处理

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接