演示异常处理之实例七

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

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

时间: 2024-07-28 13:04:22

演示异常处理之实例七的相关文章

演示中断处理的实例(实例六)

下面给出一个用于演示中断处理的实例.该实例的逻辑功能是,在屏幕的左上角以倒计时方式显示秒为单位的时间,在时间用完后结束.该实例演示内容包括:外部中断处理程序和陷阱处理程序. 1.源程序组织和清单 本实例由如下几部分组成: (1)全局描述符表GDT.GDT中除了含有常见的几个描述符外,还含有描述时钟中断处理程序所使用的代码段和数据段描述符,以及描述显示程序所使用的代码段和数据段描述符. (2)中断描述符表IDT.为了在保护模式下响应中断和处理异常,必须有IDT.IDT含有256个门描述符.8号安排

php异常处理方法实例汇总_php技巧

本文实例讲述了php异常处理方法.分享给大家供大家参考.具体如下: <?php $path = "D://in.txt"; try //检测异常 { file_open($path); } catch(Exception $e) //捕获异常 { echo $e->getMessage(); } function file_open($path) { if(!file_exists($path)) //如果文件无法找到,抛出异常对象 { throw new Exceptio

C语言库函数大全及应用实例七

原文:C语言库函数大全及应用实例七 [编程资料]C语言库函数大全及应用实例七 函数名: getw 功 能: 从流中取一整数 用 法: int getw(FILE *strem); 程序例: <?xml:namespace prefix="o" ns="urn:schemas-microsoft-com:office:office"?> #i nclude #i nclude .h>.h> #define FNAME "test.$$

php异常处理方法实例汇总

          本文实例讲述了php异常处理方法.分享给大家供大家参考.具体如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <?php $path = "D://in.txt"; try //检测异常 { file_open($path); } catch(Exception $e) //捕获异常 { echo $e->getMessage(); }   function f

ajaxToolkit:AccordionPane演示与应用实例_实用技巧

一个展开收合的ajaxToolkit:AccordionPane控件.Insus.NET在专案有用到它. 因为它可以节省显示空间.不过有点不足,就是用户刚开始使用,需要记得每个AccordionPane内容.或是需要使用一个显而可见的名字.下面的演示中,只是两个收合AccordionPane,如果多个的话,就会有上面提及的问题. 下面是HTML:ajaxToolkit:Accordion 复制代码 代码如下: <ajaxToolkit:Accordion ID="Accordion1&qu

jquery 动态演示各种排序实例代码

提示:您可以先修改部分代码再运行 <!doctype html> <html> <head> <meta charset="utf-8" /><title>快速排序(quicksort)的javascript实现-动画演示</title> <link href="css.css" type="text/css" rel="stylesheet" /&

PHP图像处理类库及演示分享_php实例

简单写了一个PHP的图像处理类库,虽然功能比较少,但是目前也没用到太高级的,以后用到了再填吧,或者哪位给点建议加上什么功能,或者有什么需求可以跟我说,我有时间加上,如果哪位对这个类库进行了扩展的话,还麻烦拿出来大家分享一下,代码现在是能用就行,考虑的东西不是很多,有什么更好的建议请告诉我,谢谢 Img.php <?php /** * Created by PhpStorm. * User: MCtion * Date: 2015/5/14 0014 * Time: 15:36 * 简单的图像类库

Java异常处理实例分析_java

本文实例讲述了Java异常处理的用法.分享给大家供大家参考.具体分析如下: Java的异常处理机制可以帮助我们避开或者处理程序可能发生的错误,从而使得程序在遇到一些可恢复的错误的时候不会意外终止,而是去处理这些错误,也使得我们在写程序的时候不必写大量的代码来检查错误情况,增强了代码的可读性和逻辑性.在Java中,异常代表一个错误的实体对象. 异常可分为两类:一类是严重错误,如硬件错误.内存不足等,它们对应着java.lang包下的Error类及其子类.通常这类错误程序自身是无法恢复的,需要中断程

Java异常处理实例教程_java

1.什么是异常? 首先,让我们来看看下图的例子: 在这个例子中,存在的错误码由除以0的结果.由于除以0而导致异常: ArithmeticException HelloException.java package com.yiibai.tutorial.exception; public class HelloException { public static void main(String[] args) { System.out.println("Three"); // This