DOS程序员手册(七)-程序员宅基地

技术标签: 运维  操作系统  c/c++  

第11章      中断处理程序

      本章将深入到DOS系统内部探讨中断处理程序的内容。与其他计算机编程不一样,

中断处理程序这个名词听起来就很难懂。用最简单的话来说,中断处理程序就是对应于中

断激活的程序。

    读者可能已发现,中断处理实际上并不是件很难办的事。事实上,在某些地方中断处

理很容易管理。但是,其中仍然有些“黑洞”,一旦陷入便不能自拔。本章的信息可让你不

致于迷失在黑洞中。

      人们谈论中断已有好多年了。当它第一次作为系统设计的主要部分而应用到计算机

上时,它就获得了不安全的名声。在早期的计算机系统上,中断常常很令人头痛,因为那时

程序员们没有处理它们的经验,并不公正地将它们视为捷径。

      长久以来,中断一直是系统程序员、各种硬件工程人员未攻克的难题,许多程序员对

此是谈虎色变。幸好,PC机为处理中断提供了一个相对宽松的环境,如果你按照一些通用

的准则编写中断处理程序的话,则你所遇到的问题也就迎刃而解。一旦你掌握了足够的经

验,你就能够毫不费力地控制中断。

    本章首先介绍中断。除了讨论软件中产生的中断外,还讨论了内部和外部硬件产生的

中断。在介绍这些之前,应该先考虑一下中断是怎样为你服务的。围绕着中断处理的讨论,

本章还介绍了几个实际操作中的例子。

      了解了中断以后,本章还将回头接着谈上一章巳开始的话题——终止并驻留(TSR)

程序。几乎每种TSR都按某种方式把自己与某一中断连接在一起,形成中断服务例程。本

章将介绍制作好的TSR的方法,并在介绍读者不太熟悉或不大容易理解的内容时穿插一

些实例。

    让我们先开始最基本的内容——探讨什么是中断。

                      11.1什么是中断

      “中断”是一种信号,它告诉处理器已发生了某件需要特别注意的事情。它用于让处理

器集中注意力来处理某件重要的事情。如果没有中断,就必须周期性地查询每一设备,并

检查设备上是否有所需要的东西。

      如果在一个查询系统上共有60种设备,并且每检查一种设备要用1秒钟,那么,每分

钟内每台设备只能检查1次。若在这种情况需要更快速的响应,那么很显然,查询方法不

适合。使用中断的原因就在于消除查询的需要,并延缓对外部事件的服务。

                                                                                           

258页

      例如,当磁盘驱动器发生信号,告诉系统它准备把一个信息扇区传送到主内存时,中

断就会产生。如果处理器对中断的响应太慢,则此块被丢失,这样,强迫处理器把所进行的

一切搁到一边,立即执行中断。

      上例中的这类中断是由外部事件产生的。内部事件也能产生中断,如计算机中出现被

零除错误或程序发出指定的执行软件中断请求,包括广泛地用于每一虚拟DOS功能的

Int 21h。

      无论计算机何时收到中断信息,它都会停下自己正在进行的一切,在程序中“标记它

的位置”,并把控制权交给中断程序,然后,中断处理程序处理急待处理的事件,并随即返

回。有些处理器只提供严格限制的中断标识,并依靠中断处理程序识别中断以及随后采取

相应的处理措施。

      通过使用中断向量来缩短启用特定中断处理程序的时间,这样便可在处理器的8086

系列上更有效地处理中断。一个中断向量就是一个指向实际处理程序例程的远指针(32

位,采用偏移值:段格式);在8086系列里,RAM的头1024个字节专门用于提供256个处

理器能识别的中断向量。

      为中断处理程序编程曾经是一种多少带点神秘色彩的艺术,很少有人知道它,在一些

较旧的系统上知之者更是廖廖无几。在一些系统上,中断处理涉及精确的定时问题,以及

处理器和计算机设计的错综复杂的知识,这些知识远远超出了经典的编程员们曾涉足过

的范围。在能产生中断的系统上,多级中断出错是威协程序员们生存的祸根,因为查找错

误的途径毫无规律可循,并且几乎不可能找到。

      然而,PC机上的中断相对来说要好处理得多,原因有两方面。一方面是因为PC类是

单用户单进程的系统,另一方面其中断结构要完善得多。虽然小心谨慎是必不可少的,但

可用这种标准的中断结构来处理下述情况的中断:

      1.当中断产生时,把处理器没有自动保存的一切内容保存起来(这意味着在处理程

序的操作期间,PC机上的全部寄存器都可能会被改变;最安全的办法就是将它们全部保

存起来,但CS、IP、SS和SP除外,可将它们压入堆栈)。

      2.禁止出现可能干涉处理程序操作的所有中断。

      3.允许在处理程序的操作期间可安全地出现的中断。

      4.处理中断。

      5.把保存的处理器寄存器恢复到步骤1。

      6.重新启用中断。

      7.返回到正常的进程。

      虽然这些信息不一定能处理好中断,但它的确能引导你小心地渡过难关。

      许多人曾遇到过这种情况——串行I/O,这种情况很难处理,除非把中断处理程序与

    串行端口连接在一起。Microsoft BASIC提供了一种用于通信的内部中断处理程序,该程

    序允许进行串行I/O操作。使用C语言、Pascal或汇编语言时,必须编写自己的处理程序。

      Ctrl-Break/Ctrl-C处理程序也是一种有用的中断处理程序,对许多程序而言,Ctrl-

Break让它们处于一种糟糕的境地——不更新文件以及等等。要按正常的方式关闭此种

 

259页

程序,Ctrl-Break处理程序会让你的程序控制退出。

                  11.2中断的工作方式

    中断产生时,处理器可处于任何状态。处理器被设计成在响应中断之前,它总是能完

成进程中的任何步骤。当处理器识别了中断时,它迅速作出响应:把标志寄存器(程序状态

字)、指令指针(IP)和代码段寄存器(CS)压到堆栈上,并禁止中断。

    保存了关键机器状态信息之后,处理器在系统总线中查找一个8位数——中断请求

级(IQR)。该级能准确地识别是哪一设备发出了中断,并让处理器知道用哪一向量作出响

应。前面已解释过,中断向量是指向用于指定功能的实际处理程序例程的指针。

    8086 PC(和它的后续系列)把一个固定为8的偏移值加上中断的设备提供的数字来

确定中断信号是否已发出。例如,IRQ 0级产生Int 08h,并且IRQ第7级产生Int 0Fh(在

AT和PS/2设计中,把这一处理进行了修改,它们能识别超过8个的中断请求级,但原理

仍然相同)。

    处理器把Int号乘以4来把其偏移值保存到中断向量表(interrupt vector table)中。然

后查看段0000h以找到该向量。该向量的内容被置入CS : IP,并自动地控制处理中断的

程序(中断处理程序)第一道指令的发出。

    在处理器使用中断处理程序期间,中断处理程序便控制着该处理器。大多数处理程序

首先重新启用中断以便能服务于有更大优先权的中断。它们还保存它们使用的全部寄存

器,然后尽快地执行它们自己的操作。对于有些设备,必须传送特殊的接收信号,以便让该

设备知道它已被服务过。处理程序必须在需要的地方提供这种特殊信号。

    通常情况下,必须把中断处理程序尽可能地编写得既精简又快速,其中大多数是用汇

编语言写成的,这样可消除所有多余的开销,并确保该程序尽可能快速地运行。也可以用

C语言编写处理程序(本章列举了几个C语言的例子),但是必须用尽量少的开销来处理

关键时间(time—critical)中断。

    通过8259A可编程的中断控制器(PIC)引发的中断(IRQ产生的硬件中断)必须在处

理完毕时把一个终止中断的信号发送给PIC。中断处理完毕后,所有的中断处理程序都必

须恢复机器的状态,具体步骤是先恢复全部保存的寄存器,然后执行中断返回(IRET)指

令来把标志寄存器、CS和IP恢复到中断产生前的值。

              11.3 Intel 8086系列的中断类型

    8086微处理器系列上的中断可分为三种基本类型。这一节将分别讨论这三种中断类

型:

      ·内部硬件中断

      ·外部硬件中断

      ·软件中断

 

260页

11.3.1内部硬件中断

      在处理器中设计内部硬件中断是为了处理一些特殊的情况,诸如被零除出错或其它

一些处理器已意识到出错的情况。这些情况列于表11.1中。

                                    表11.1内部硬件中断

                                    (a)8086处理器硬件中断

中断级                  向里偏移值(地址)        含义

    00h                        00h                    被零除

    01h                        04h                    单步

    02h                        08h                    不可屏蔽中断

    03h                        0Ch                    断点

    04h                        10h                    溢出

(b)80286处理器硬件中断

中断级                  向里偏移值(地址)          含义

    05h                      14                     超出界限范围

    06h                      18h                    无效的操作码

    07h                      1Ch                    处理器扩展不可用

    08h                      20h                    双重异常

    09h                     2411                    段超限

    0Ah                      28h                    非法任务状态段

   0Bh                     2Ch                     不存在的段

    0Ch                      30h                    堆栈段超限

   0Dh                     34h                     通用保护故障

      不能把这些中断直接用于程序。在基本的PC机设计中,IBM重新安排了其中的一些

中断(8086/80286的最初设计中没有用到,但出现在后来的扩展版本中)来处理其它的情

况。在下代芯片(80186)问世时,冲突出现了,并且一直延续到今天,这种冲突源于8086系

列芯片的设计与IBM对中断向量的使用。出现这种情况并不是什么好事,但我们必须处

理它。表11.2列出了IBM指定的中断向量。比较表11.1和11.2,不难看出其中相冲突

的地方。

11.3.2外部硬件中断

      处理器可连接外部硬件中断来允许设备发出中断信号。早期大多数使用中断的微型

计算机就是按这种方式建成的。有两种连接方式可用:不可屏蔽的中断(NMI)和可屏蔽

的中断(INTR)。仅仅从名字上判断,应该可以关掉INTR,但不能切断NMI。

      当不想因为任何理由而终止中断时,可使用NMI中断。在一些系统上,把物理重设置

开关以线接的方式连接上NMI中断,操作员便能获知处理器的全部动向。

      把INTR中断线接到8259A PIC中可利用芯片的优先列入功能,并可在软件控制下

 

261页

控制中断。处理器指令能直接允许和禁止中断,并且加给PIC的指令能有选择地允许和

禁止中断。

    但是,中断是设置在硬件层上的。在某些产品中,生产厂商还设置了中断级,并且丝毫

无法改变它们。一些设置提供开关或跳转程序,它们只能在有限范围值内重新设置中断

级。

                        表11.2中断向量

向量         行    为

00h           被零除

01h           单步

02h           不可屏蔽中断

03h           断点

04h           溢出

05h           打印屏幕

06h           未使用

07h           未使用

08h           硬件IRQ0(计时器计时)

09h           键盘输入中断

0Ah           保留

0Bh           异步端口控制卡1(COM2

0Ch           异步端口控制卡0(COM1

0Dh           硬盘控制卡

0Eh           软盘控制卡

0Fh           打印机控制卡

10h         视频驱动程序

11h           设备配置检查

12h           内存大小检查

13h           软盘/硬盘(PC/XT)

14h           通信端口驱动程序

15h           磁盘/网络服务

16h           键盘驱动程序

17h           打印机驱动程序

18h             ROMBASIC

19h           重启动系统

1Ah           设置/读实时时钟

1Bh          Ctrl-Break处理程序

1Ch           计时器计时(用户定义)

1Dh           视频参数表

1Eh           磁盘参数表

1Fh           图形字符表(字符80h-FFh)

20h           程序终止

21h            DOS功能调度程序

22h           终止向量

23h            Ctrl-C向量

24h           关键出错向量

25h           绝对磁盘读

26h           绝对磁盘写

27h           终止并驻留

28h           DOSOK中断

2Fh           多路复用中断(见参考手册部分)

40h           软盘驱动程序(PC/XT)

41h           硬盘参数表

43h           图形字符表

11.3.3软件中断

    软件中断是这样产生的:程序发出软件中断指令给处理器,使得处理器像接收到硬件

中断一样采取行动。这种方法通常用来访问与程序无关的DOS和BIOS服务程序。根据

需要,可把这两种服务程序链接到指定的中断上,然后改变它们,并丝毫不影响调用它们

的应用程序。

 

262页

                       11.4中断向量

        中断向量表被保存在系统内存中最低的1024个字节中,每个中断向量占用四个字

    节,一共有256个不同的中断向量。相应功能中断处理程序的偏移值和段地址组成了每个

    四字节的项。在有些情况下,向量也包含数据值表的地址,而不是程序的地址,如Int 1Fh

    所指的图形字符表。

                    11.5获取和设置中断向量

        有关中断向量的所有警告会让你警觉到中断量可能具有的任何影响都有其破坏性的

    一面。设想某一程序正在改变四字节中断向量中的两个字节,那么,需要使用正在改变的

    中断向量的另一进程的中断使正在执行的用户程序暂停,并使CPU跳转到一个未完成的

    向量地址上,从而可能在内存中的任何地方不可预知地中止。这种情况常常导致“挂起”你

    的计算机,有时甚至会冲掉你的硬盘。

        这一过程是如何实现的呢? DOS是一种单任务系统,一次只能进行一种操作。但是,

    对应于硬件中断的另一种中断服务例程会简单地采取控制并让你的程序半路上接通它。

    许多TSR在被激活时就获得了控制权,并在任务完成后把中断归还给它们的初始设置,

    这种情况确实可以出现。在编程过程中,任何实际将发生的事情都能够发生;问题只在于

    它发生得早或迟。

        更为重要的是向上兼容性的问题。直接修改中断向量与后来的DOS升级版本不兼容

    (如果把OS/2看作是一种升级的话,那么也包括它)。虽然目前已能直接进行修改,但绝

    对不能在多任务系统上进行。倒是DOS提供了改变一个中断向量的安全途径—使用

    Int 21h的功能25h(设置中断向量)和35h(获取中断向量)。

        1.使用功能35h来获取当前向量值,并把此值保存起来,留待以后在链接已使用中

    断的程序以及保存此中断时使用。

        2.使用功能25h来设置中断向量。

        这一过程简单地采用了汇编语言来编写(参见列表11.1)。

        列表11.1

              ; GetSet.asm

              ;----Get the Ctrl-C vector----

                  mov        ah, 35h         ;Get vector

                  mov        al , 23h        ;Ctrl-C

                  int        21h

              mov      oldseg ,es   ; Store old vector

              mov      oldoff,bx

          ;----Set the Ctrl-C vector----

 

263页

       mov    ah,25         ;set vector

            mov      al,23h        ;Ctrl-C

            mov      dx , seg c_hand

            mov     ds,dX

            mov     dx,offset c_hand

      int 21h

    无须在DOS层上设置中断。可用的高级语言服务程序有助于清晰地设置中断,并消

除它们在遇到问题时可能分散注意力。这些高级语言程序在执行Int 21h的功能25h和

35h服务时显得更方便。

    Borland C/C++提供了两种函数—getvect()和setvect(),它们在不调用DOS功能

的情况下,就能做到与DOS功能35h和25h一样的事情。在MicrosoftC/C++中,

dos_getvect和_dos_setvect函数也执行同样的操作,而在Turbo Pascal中,执行这些操作

的是GetlatVec和SetIntVec函数。

          11.6什么时候必须写一个中断处理程序

      在下述几种情况下,有必要创建自己的中断处理程序:

      ·必须捕获中断并防止程序在不正常情况下失败。编写商用程序时,决不能让用户在

        出现被零除错误或其它一些错误时“炸毁”于应用程序。应用程序必须处理出错。进一

      步地讲,若程序在执行任何“令它喜爱的”操作时,必须捕获Ctrl-C和Ctrl-Break事

      件,并处理它们,而不能让系统中断。

      ·必须链接到中断链中。在这方面的两个例子是:编写在某些固定击键上执行的TSR

      和编写希望在程序中用到的特殊定时程序。

      ·必须控制串行端口。前面曾提到,DOS并不为串行端口提供充足的服务。若想编写

        实际用的终端程序,那么,它必须具有中断驱动的、串行端口的服务例程。

      在除此之外的情况下,必须尽可能地用高级语言编写代码。如果能用高级语言编写中

断处理程序的代码,那么无论如何都得这样作,除非该中断处理程序在程序中运行得不够

快。用高级语言进行调试比用汇编语言要容易得多。若处理程序运行得不够快,可随时将

它重新进行编码。

      只要有可能,应尽量使用高级语言函数来处理中断。Borland C/C++提供的ctrlbrk

()函数可用于从高级代码模式中设置Ctrl-C中断处理程序。Microsoft C/C++提供的

UNIX兼容的signal()函数用于处理信号捕获。除了其它命令之外,QuickBASIC还提供了

用于处理事件的ON KEY和TIMER命令。Turbo Pascal能处理那些有直接插入的汇编

代码或使用Interrupt伪指令的中断。因此,应尽可能地选择能完成这项工作的高级语言。

      编写中断处理程序时,若无特殊的需要,一般不要使用DOS型的功能。DOS是不可

重入的;若DOS在进行某件事时被中断,那么当再次调用DOS功能时,会很容易锁定系

统。

      有一种方法可不调用DOS功能,即让中断处理程序做些设置进程的工作(例如把数

 

264页

    据复制到缓冲区内)。中断处理程序可设置一种标志,当前正在使用系统去做其它处理的

    程序能识别此标志,从而可防止它可能去调用DOS功能。更透彻地讲,DOS用一些隐藏

    的方法来确定DOS调用在什么时候是安全的。那些花大量的时间去猜测别人是如何执行

计算机技术的人已发现并公布了一些学习DOS所作的方法。

        首先,Int 21h功能(功能34h)通过ES:BX寄存器返回一个指针,该指针指向一个

    DOS忙碌标志,我们称此标志为InDOS标志。此标志是深藏在操作系统内核中的一个单

    字节。不管Int 21h功能何时启动,此标志都减去1;当这一功能终止时,该标志001。当该标

    志为0时,就表示没有执行任何DOS功能。

      无论什么时候按下TSR的热键,它都检查InDOS标志。若此标志非零,TSR在其自

    身内设置一热键标志。然后这样做的TSR连接时钟中断,并且每秒检查InDOS标志18.2

    次,直至该标志清除。当InDOS被清除而此热键标志还设置着的时候,TSR开始它自己的

    操作。

        这种处理虽然好,只是在命令处理器等待用户敲入命令行时,它让用户干等着。因为

    命令处理器使用DOS功能来进行命令行输入,在DOS等待字符时,InDOS标志已设置。

    很明显,DOS正处于安全的位置,如果不用这些DOS功能进行控制台I/O操作的话,那

    么,其它的操作就能中断DOS。为了允许控制台I/O操作的进行,DOS使用了另一种中断

功能—28h,当控制冶输入程序在等待输入时,它们会重复地调用这一功能。这种中断

为DOS空闲(或DOSOK)中断。

      DOS空闲中断通常执行中断返回(IRET),IRET返回控制权给控制台输入程序。如

果将TSR链接上这种中断,并注意到热键标志已打开时,那么就可以立即执行TSR。

      使用中断时,应确保遵循这样一条规则——应一直假设可以调用其它程序。例如,绝

对不能直接设置中断向量。Int 21h的功能25h就是用于这一目的的服务,并防止两种程

序在设置中断向量时出现混淆。除非编写像Ctrl-C处理程序之类的内容,否则,必须保存

初始的处理程序向量,并在完成进程时才能对它进行分支。也可以安装另一种需要激活的

处理程序。若不遵守这种简单的规则,在实际操作中就会遇到麻烦。

    程序终止时,它必须清除它曾设置的所有中断处理程序(系统自动地清除关键出错和

Ctrl-C处理程序)。例如,若编写终端程序,那么在终止此程序之前,必须恢复初始的中断

处理程序,从而防止中断出现在处理程序所在的地方。若程序将设置常驻程序,则必须使

用TSR终止,以便处理程序能永久地获得它所需的内存,并不致于被改写。

                11.7编写Ctrl-C处理程序

      简单的Ctrl-C处理程序可作为中断处理的范例。该处理程序所表现出的几个阶段说

明,有几种方法可处理中断问题。

      在第一个例子中,Borland C/C++使用ctrlbrk()函数来创建完全使用C语言的处理

程序(见列表11.2)。Handle.c 允许中断正在进行的进程,并确定是否取消中断。因为ctrl-

brk()函数处理异常中止,并根据对提示问题的回答返回适当的代码。这种编写程序的方

法特别简单方便,因为它使用高级语言,编完就能用,并且不涉及太复杂的编程。更进一步

 

265页

讲,Borland C/C++显示出此程序可以使用longjmp(长跳转)和其它一些功能来直接与

高层的程序发生交互作用。

    列表11.2

          /* handler.c

              Listing 11.2 of DOS Programmer's Reference*/

          #include<stdlib.h>

          #include<stdio.h>

          #include<conio.h>

          #include<dos.h>

          #define         CR   0x0D

          #define         LF   0x0A

          int handler(void);

          void main()

          {

              int      c;

              int     i;

              if(getcbrk()==0)

                  printf("BREAK checking is 0FF\n");

              else

                  printf("BREAK checking is ON\n");

              ctrlbrk(handler);

              for(i=0;  i<250;  i++){

                  printf("%4.4d : Testing Ctrl-Break\n",i);

              }

              printf("\nCharacter input\n");

              printf("press any key;  test Ctrl-Break\n");

            printf("if all else fails, press Esc to exit)\n\n");

          while((c=getche())!=27)

              if(C==CR||c==LF)

                  putchar(LF);

        }

        handler()

        {

            int    c;

          printf("\nCtrl-Break handler\n");

          printf("Do you want to quit?");

          while((c=getch())!='y' && c!'Y'&& c!'n' && c!='N');

          printf("\n");

          return ((C=='Y'||c=='y':)?0:1));

        }

    Handler.c 做了两件事来允许你测试Ctrl-C处理:

    1.在屏幕上,它显示出可以用Ctrl-C或Ctrl-Break中断的250行重复内容。

    2.它接收键盘敲入的字符信息,这样,在键盘输入期间,可以使用ctrl-C或ctrl-

Break。

    虽然汇编语言函数简单得多,但直接用汇编语言编码的函数使用起来几乎能使ctrl-

brk()函数以假乱真。之所以必须使用汇编语言,是因为必须通过中断返回(JRET)而不是

普通函数返回来完成处理程序。虽然可在此处理程序中来用直接插入码(嵌入式汇编),只

是其效果没有采用汇编语言那么好。

 

266页

      优秀的汇编语言编程人员能直接编写出中断处理程序,但是大多数人可能不知道怎

    样去拼凑出中断处理程序。要创建这种汇编语言程序,可从一道空的C程序开始,并把它

    编译成汇编语言源代码:

          set_brk()

          {

          }

          brk()

          {

          handler();

          }

      通过Borland C/C++,我们就可以这样来编译此代码:

          C>bcc.s set_brk.c

        获取汇编语言源码的过程列于列表11.3。

    列表11.3

                  ifndef ??version

      ?debug macro

                  endm

      publicdll macro name

                  public     name

                  endm

      $ comm      macro     name  ,dist, size,conunt

                  comm dist name:BYTE:count*size

                  endm

                  else

      $comm     macro     name,dist,size ,  count

                  comm      dist name [size]:BYTE : count

                  endm

                  endif

                  ?debug V  300h

                  ?debug S "set_brk.c"

              ?debug C E9EC837A1A097365745F62726B2E63

      TEXT     segment byte public'CODE'

       _TEXT      ends

      DGROUP  group  _DATA,_BSS

              assume  cs:_TEXT,ds :DGROUP

      DATA     segment word public 'DATA'

      d@    label    byte

      d@w  label word

       _DATA      ends

     _BSS    segment word public 'BSS'

      b@      label    byte

      b@w     label word

       _BSS      ends

     _TEXT     segment byte public 'CODE'

                        ;

          ;   set_brk()

                          ;

                  assume    CS:_TEXT

       _set_brk            proc        near

                  push       bp

                  nov       bp,sp

                          ;

 

267页

      ;    {

      ;    }

                  ;

            pop       bp

                ret

     _set_brk                 endp

                  ,

      ;    brk()

                  ;

              assume    cs :_TEXT

     _brk    proc         near

              push         bp

              mov         bp,sp

                  ;

        ;  {

        ;       handler();

                  ;

            call     nearptr_handler

                  ;

        ;    }

                    ;

            pop       bp

            ret

   _brk    endp

            ?debug C E9

            ?debug C FA00000000

   _TEXT   ends

    DATA     segment word public 'DATA'

    s@      label      byte

   _DATA    ends

    TEXT     segment byte public 'CODE'

   _TEXT    ends

            extrn   _handler:near

            public   _brk

            public   _set_prk

   _s@      equ        s@

            end

    这个空的C程序(有时叫做NULL程序)产生了一种空例程,用它可建立中断处理程

序。我们可能需要跋涉过C编译程序所插入的不重要信息(如调试信息),但是,如果对汇

编语言不熟悉,则这类信息会节约一点时间。一些汇编语言“高手”也许会嘲笑这种方式,

但专业化的程序员已多年利用这种方法来了解编译程序产生代码的方式,或者提供一种

方式,用汇编语言重新编码某个功能,以便节省处理时间。

                              建立汇编语言例程

        一本正经的汇编语言程序员可能害怕这种想法,但确实可以这样准备一个

    汇编语言例程:首先用高级语言如C编写一个例程,然后用可以产生汇编语言

    源代码的选项来编译该例程。列表11.3的实例中,开发时间已显著减少,因为该

    例程的骨架是从编译程序产生的。

      如果必须产生汇编语言程序或者如果想优化用高级语言编写的程序,那么

    这项技术是不错的。把程序转换成汇编码,并编辑所形成的文件,这可以在最小

    量的时间内提供一个工作程序。

268页

      在Turbo Pascal 4.0及更高版本中,可以声明带有interrupt指令的程序为中断处理程

    序。编译程序自动操纵寄存器和IRET指令。该程序可保存所有寄存器;如果只需要保存

    几个,那么自己直接写的汇编代码可能更有效。

      列表11.4

   _TEXT       segment byte public 'code'

     _TEXT         ends

    DGROUP group  _DATA,_BSS

            assume CS:_TEXT , ds : DGROUP

    DATA     segment wordpublic'DATA'

    d@       label     byte

    d@w         label    word

     _DATA    ends

    _BSS       segment word public 'BSS'

    b@          label        byte

    b@w         label    word

     _BSS      ends

    _TEXT       segment byte public 'CODE'

                    ;

        ;  set_brk()

                      ;

                  assume       cs :_TEXT

   _set_brk          proc      near

                    ;

        ;    {

                push      bp            ;save the registers

                push       ds

                push       di

                push       si

                mov        dx , CS

                mov        ds , dX

                mov        dx , offset_brk

                mov        ah , 25h    ;Set interrupt vector

                mov        al , 23h    ;Ctrl-C handler

                int       21h

                pop        si           ;Retrieve the registers

                pop        di

                pop        ds

                pop        bp

                    ret

        ;  }

                    ;

   _set_brk          endp

                    ;

        ;    brk()

                    ;

                assume cs :_TEXT

     _brk      proc         near

              push       ax            ; Save the registers

              push       bx

              push       cx

              push       dx

              push       di

              push       si

              push       bp

                      ;

        ;    {

        ;        handler();

                      ;

            call      near ptr_handler

 

269页

      ;

      ;    }

      ;

            pop     bp          ;Retrieve the registers

                  pop         si

                  pop          di

                  pop          dx

                  pop          cx

                  pop          bx

                  pop         aX

                  iret

     _brk    endp

      _TEXT     ends

    DATA     segment word public‘ DATA’

    s@      label   byte

     _DATA    ends

    TEXT     segment byte public'CODE'

      TEXT      ends

                extrn     _handler:near

          public        _brk

            public_set_brk

   _s@      equ      s@

            end

    注意除编译程序提供的代码以外,没有清除别的代码;不过,它移动了调试码。一些附

加的技巧已经被去掉(汇编语言编程高手会做到这一点),但这并非必不可少。唯一的要求

是代码能工作。它做得到这一点。

    最后,修改的handler.c程序见列表11.5。

    列表11.5

        /* handler2.c

        Listing 11.5 of DOS Programmer's Reference*/

        #include<stdlib.h>

        #include<stdio.h>

        #include<conio.h>

        #include<dos.h>

        #define          CR     0x0D

        #define        LF    0x0A

        int  handler(void);

        void main()

        {

            void     set_brk(void);

            int      c;

            int      i;

            if(getcbrk()==0)

          printf("BREAK checking is OFF\n");

            else

            printf("BREAK checking is ON\n");

        set_brk();

        for(i=0; i<250; i++){

            printf("%4.4d:Testing Ctrl-Break\n", i) ;

          }

270页

          printf("\ncharacter input\n");

          printf("Press any key; test Ctrl-Break\n");

        printf("(if all else fails, press Esc to exit)\n\n");

          while((c=getche())!=27)

              if(c==CR||c==LF)

                  putchar(LF);

        }

        handler()

        {

            int    c;

            printf("\nCtrl-Break handler\n");

            printf( "Do you want to quit?");

          while((c=getch())!='y' && c!='Y'  && c!='n' && c!='n');

            printf("\n");

            if(c=='y'||c=='y')

              exit(0);

            return (0);

        }

      编译该程序,并把它连接到汇编语言例程上,这样就能产生一个可以工作的Ctrl-C

处理程序。应该用下列命令行来使用BorlandC/C++编译程序来编译该程序:

        bcc handler2.c set_brk2.asm

              11.8编写一个关键出错处理程序

      关键出错处理程序可能是我们能编写的最复杂的中断处理程序。错误出现时,DOS

引入该程序并给用户某种能力决定越过这个问题还是中止程序。标准的DOS表示就是

Abort,Retry,Fail?(退出,重试,失败)提示。程序员应将这个信息看作大祸临头,它不注意

我们细心设计的屏幕,并且只略微注意已发生的事情。其实DOS已向关键出错处理程序

提供有关已发生事情的大量信息。

      列表11.6中的代码是能综合进一个完全的应用程序中的TASM模型;它利用了这笔

信息财富。

    列表11.6

      page55,132

        ;CritErr.asm

        ;functions for creating a pop- up critical error handler

      criterr_data      segment

      .MAXLIHES  equ 19

            oldcritErroffset                 dw   (?);Old critical error address

            oldCritErrSegment                   dw   (?)

            DeviceDriverHeaderoffset            dw   (?) ; Device driver address

            DeviceDriverHeaderSegment            dw   (?)

            ErrorCode                          dw   (?) ; Error code on entry

            Line                                 dw MAXLINES dup(?);Pointers tO menu lines

      、     ooS*3j oPVersion                    db   (?)  f DOSmajor versiOn

            10 Type                              db   (?) ; I/O type of error

            DriveNuntber                        db   (7) ;Which drive had error

            *enuLines                           db   (?) ;Number of lines on screen- 1

            Currentoption                        db   (?)  ;  Currently selected option

 

271页

MaximumOption     db (?) ; Number of valid options - 1

ReturnCodes       dw (?) ; Pointer to list of valid return codes

TopLine           db (?) ; Top line of window

BottomLine         db (?) ; Bottom line of window

LeftRow            db (?) ; Left line of window

RightRow          db (?) ; Right line of window

ActiveDisplaypage  db (?) ; Active display video page

originalRow        db (?) ; Where cursor was

originalColumn    db - l ? j ,

set_2_       db 2

Set23           db 2 , 3

Set_12_         db 1 , 2

Sett_123        db 1 , 2 , 3

Set0_2_        db 0 , 2

Set0_23        db 0 , 2 , 3

Set012_        db 0 , 1 , 2

Set0123        db 0 , 1 , 2 , 3

ATTRIBUTE equ 17H ; WHITE ON BLUE

TopMenu                db     "          Critical Error               "

UnknownFunction        db     "          Unknown    DOS Function      "

Fn_00                  db     "           Terminate Program Line      "

fn_01                  db     "           keyboard Input With Echo    "

fn_02                  db     "                Display Output         "

fn_03                  db     "                 Auxiliary Input       "

fn_04                  db     "               Auxiliary Output        "

fn_05                  db     "           Printer Output              "

fn_06                  db     "          Display Console I/O           "

fn_07                  db     "          Direct STDIN Input           "

fn_08                  db     "             STDIN Input               "

fn_09                  db     "                Display String         "

fn_0a                  db     "             Buffered STDIN Input      "

fn_0b                  db     "          Check STDIN Status           "

fn_0c                  db     "        Clear Buffer And Input         "

fn_0d                  db     "                 Reset Disk            "

fn_0e                  db     "             Select Disk               "

fn_0f                  db     "                 Open File(FCB)        "

fn_10                  db     "                Close File (FCB)       "

fn_11                  db     "     earch For First Entry (FCB)       "

fn_12                  db     "      Search For Next Entry (FCB)      "

Fn_13                  db     "                 Delete File(FCB)      "

Fn_14                  db     "       Read Sequential File(FCB)       "

fn_15                  db     "     Write Sequential File (FCB)       "

fn_16                  db      "     Create File (FCB)                "

fn_17                  db     "             Rename File(FCB)          "

fn_19                  db    "            Get Default Drive           "

fn_1A                  db     "                Set DTA Address        "

fn_1b                  db     " Get Allocation Table Information        "

fn_1c                 db     " Get Allocation Table Information For Specific Drive "

fn_1f                  db "     Get Default Disk Parameter Block       "

fn_21              db "Random File Read (FCB)       "

fn_22        db  "Random File Write (FCB)         "

fn_23         db " Get File Size(FCB)          "

fn_24        db " Set Random Record Field (FCB)        "

fn_25      db   "Set Interrupt Vector          "

fn_26            db "Create PSP              "

fn_27        db "Random Block Read(FCB)            "

fn_28         db  " Random Block Write(FCB)         "

fn_29          db "Parse File Name           "

fn_2A             db "Get System Date            "

fn_2B          db "Set System Date               "272页

Fn_3C db                "Get System Time"                             

Fn_2D db                "Set system Time"                   

Fn_2E db                "Set verify Flag"                  

Fn_2F db                "Get DTA Address"                  

Fn_30 db                "Get DOS Version Number"           

Fn_31 db                "Terminate And stay Resident"      

Fn_32 db                "Get Drive Parameter slock"        

Fn_3300 db              "Get Ctrl-Break Flag"              

Fn_3301 db              "Set Ctrl-Break Flag"              

Fn_3305 db              "Get Boot Drive Code"              

Fn_34 db                "Return Address of InDOS Flag"     

Fn_35 db                "Get interrupt Vector"             

Fn_36 db                "Get Free DiSk Space"              

Fn_3700 db              "Get Switchchar"                   

Fn_3701 db              "Set Switchchar"                   

Fn_3702 db              "Read DeviCe AVailability"         

Fn_3703 db              "set Device AVailability"          

Fn_38 db                "Get Set Country information"      

Fn_39 db                "Create Subdirectory"              

Fn_3A db                "Remove Subdirectory"              

Fn_3B db                "Set Directory"                    

Fn_3C db                "Create Truncate File Handle"      

Fn_3D db                "open File Handle"                  

Fn_3E   db              "Close File Handle"                

Fn_3F db                "Read File or Device Handle"       

Fn_40 db                "Write TO File or Device Handle"   

Fn_41 db                "Delete File"                       

Fn_42 db                "Move File Pointer"                

Fn_4300 db              "Get File Attributes"              

Fn_4301 db              "Set File Attributes"              

Fn_4400 db              "Get Device information"           

Fn_4401 db              "Set Device information"           

Fn_4402 db              "Device IOCTL Read"                

Fn_4403 db              "Device IOCTL Write"               

Fn_4404 db              "Block Driver IOCTL Read"          

Fn_4405 db              "Block Driver IOCTL Write"         

Fn_4406 db              "Get input Status"                 

Fn_4407 db              "Get output status"                

Fn_4408 db              "Block Device Removable"           

Fn_4409 db              "Block Device Local"               

Fn_440A db              "Handle Local"                     

Fn_440B db              "Set Sharing Retry Count"          

Fn_440C db              "Generic IOCTL Handles"            

Fn_440D db              "Generic IOCTL Block Devices"      

Fn_440E db              "Get Logical Drive Map"            

Fn_440F db              "Set Logical Drive Map"            

Fn_4410 db              "Query IOCTL Handle"               

Fn_4411 db              "QUery IOCTL Device"                

Fn_45 db                "Duplicate Handle"                 

Fn_46 db                "Force Duplicate Handle"           

Fn_47   db              "Get Current Directory"            

Fn_48 db                "Allocate Memory"                  

Fn_49 db                "Release Memory"                   

Fn_4A db                "Modify Memory Allocation"         

Fn_4B00 db              "Execute Program"                  

Fn_4B01 db              "Load Program"                     

Fn_4B03 db              "Load overlay"                     

Fn_4B05 db              "Enter Exec State"                 

Fn_4c db                "Terminate With Return Code"       

Fn_4D db                "Get Return Code"                  

Fn_4E db                "Search For First Match"           

Fn_4F db                "Search For Next Match"            

273页

Fn_50 db              "Set PSP Segment "                                                                                                 

Fn_51 db              "Get PSP Segment"                                                                                            

Fn_52 db              "Get Disk LiSt"                                                                                               

Fn_53 db              "Translate BPB To DPB"                                                                                       

Fn_54 db              "Get Verify Flag"                                                                                             

Fn_55 db              "create PSP"                                                                                                 

Fn_56 db              "Rename File"                                                                                                 

Fn_5700 db            "Get File Date And Time"                                                                                     

Fn_5701 db            "Set File Date And Time"                                                                                      

Fn_5800 db            "Get Allocation Strategy"                                                                                    

Fn_5801 db            "Set Allocation Strategy"                                                                                     

Fn_5802 db            "Get UMB Link Status"                                                                                        

Fn_5803 db            "set UMB Link"                                                                                                

Fn_59 db              "Get Extended Error information"                                                                             

Fn_5A db              "Create Uniquely Named File"                                                                                  

Fn_SB db              "Create New File"                                                                                            

Fn_5C00 db            "Set File Access Locks"                                                                                      

Fn_5C01 db            "clear File Access Locks"                                                                                     

Fn_5D00 db            "Copy Data TO DOS Save Area"                                                                                 

Fn_5D06 db            "Get Critical Error Flag Address"                                                                             

Fn_5D0A db            "Set Error Data Values"                                                                                      

Fn_5E00 db            "Get Machine Name"                                                                                            

Fn_5E01 db            "Set Machine Name"                                                                                           

Fn_5E02 db            "Set Network Printer Setup"                                                                                   

Fn_5E03 db            "Get Network Printer Setup"                                                                                  

Fn_5F02 db            "Get Redirection LiSt Entry"                                                                                  

Fn_5F03 db            "set Redirection LiSt Entry"                                                                                 

Fn_5F04 db            "Cancel Redirection List Entry"                                                                               

Fn_60 db              "Expand Path Name string"                                                                                    

Fn_62 db              "Get PSP Address"                                                                                             

Fn_6300 db            "Get system Lead Byte Table"                                                                                 

Fn_6301 db            "Set/Clear Interim Console Flag"                                                                             

Fn_6302 db            "Get Value of interim Console Flag"                                                                          

Fn_64 db              "Set Current Country Byte"                                                                                   

Fn_65   db            "Set Extended Country information"                                                                           

Fn_6600 db            "Get Global Code Page"                                                                                       

Fn_6602 db            "Set Global Code Page"                                                                                       

Fn_67 db              "Set Handle Count"                                                                                           

Fn_68 db              "Flush Buffer"                                                                                               

Fn_6A db              "Extended open Create"                                                                                       

Fn_6C db              "Error Code: Unknown"                                                                                        

UnknownErrorCode db   "Error Code: Write Protect Error"                                                                            

ErrorCOde00 db        "Error Code: Unknown Unit"                                                                                    

ErrorCode01 db        "Error Code: Drive Not Ready"                                                                                

ErrorCode02 db        "Error Code: Unknown Command"                                                                                 

ErrorCode03 db        "Error Code: Data Error"                                                                                     

ErrorCode04 db        "Error Code: Bad Request Structure Length"                                                                    

ErrorCode05 db        "Error Code: Seek Error"                                                                                     

ErrorCode06  db       "Error Code: Unknown Media Type"                                                                              

ErrorCode07 db        "Error Code: Sector Not Found"                                                                               

ErrorCode08 db        "Error Code: Printer out Of Paper"                                                                            

ErrorCode09 db        "Error Code: Write Fault"                                                                                    

ErrorCode0A db        "Error Code: Read Fault"                                                                                      

ErrorCode0B db        "Error Code: General Failure"                                                                                

ErrorCode0C db        "Error Code: Invalid Disk Change"                                                                             

ErrorCode0F db        "AX = "                                                                                                      

L2 db                 "0000 BX ="                                                                                                   

L2AX db               "0000 CX = "                                                                                                 

L2BX db               "0000 DX = "                                                                                                  

L2CX db               "0000     "                                                                                                  

L2DX db               DI = "                                                                                                        

L3 db                 "0000 BP = "                                                                                                 

L3DI db

L3SI  db

274页

L3BP db "                         "00000 SP = " 

L3SP db "                         "0000   "       

L4   db "                         "        DS = " 

L4DS db "                         "0000 ES = "     

L4ES db "                         "0000 SS = "     

L4SS db "                         "0000      "    

L5   db "                         "CS : IP = "      

LSCS db "                         "0000: "         

L5IP db "                         "0000 Flags = " 

LSFlags db "                      "------- "      

L7_Char db "                      "Device:  "     

L7_DeVice db "                                    

L7_UnknownChar db "               "Unknown Character (?) Device            " 

DiskError0  db "                  "Drive : Error Reading MS-DOS Area       " 

DiskError1 db "                   "Drive : Error Writing MS-DOS Area       " 

DiskError2  db "                 "Drive : Error Reading FAT               " 

DiskError3 db "                   "Drive : Error Writing FAT               " 

DiskError4   db "                 "Drive : Error Reading Root Directory    " 

Diskerror5   db    "              "Drive : Error Writing Root Directory    " 

DiskErrOr6 db "                   "Drive : Error Reading Files Area        " 

DiskError7 db "                   "Drive : Error Writing Files Area        " 

DRIVE_OFFSET equ 7                                                       

Bridge2Line db "                                        

EEC_01 db "                      "Extended Error Code Invalid Function Number     "                            

EEC_02 db "                      "Extended Error Code File Not Found              "                           

EEC_03 db "                      "Extended Error Code Path Not Found              "                             

EEC_04 db "                      "Extended Error Code No Handles Available        "                                  

EEC_05 db "                      "Extended Error Code Access Denied               "                                                               

EEC_06 db "                      "Extended Error Code Invalid Handle              "                                                               

EEC_07 db "                      "Extended Error Code Memory Ctrl Blocks Destroyed"                                                               

EEC_08 db "                      "Extended Error Code Insufficient Memory         "                                                              

EEC_09 db "                      "Extended Error Code Invalid Memory Block Address"                                                              

EEC_0A db "                      "Extended Error Code Invalid Environment         "                                                               

EEC_0B db "                      "Extended Error Code Invalid Format              "                                                                

EEC_0C db "                      "Extended Error Code Invalid Access Code         "                                                                

EEC_0D db "                      "Extended Error Code Invalid Data                "                                                                

EEC_0F db "                      "Extended Error Code Invalid Drive               "                                                         

EEC_10 db "                      "Extended Error Code Remove Current Directory    "                                                                 

EEC_11 db "                      "Extended Eeror Code Not the Same Device         "                                                             

EEC_12 db "                      "Extended Error Code No More Files               "                                                               

EEC_13 db "                      "Extended Error Code Disk write - Protected      "                                                               

EEC_14 db "                      "Extended Error Code Unknown Unit                "                                                                

EEC_15 db "                      "Extended Error Code Drive Not Ready             "                                                                 

EEC_16 db "                      "Extended Error Code Unknown Command             "                                                                

EEC_17 db "                      "Extended Error Code CRC Error                   "                                                                

EEC_18 db "                      "Extended Error Code Bad Request Structure Length"                                                                 

EEC_19 db "                      "Extended Error Code Seek Error                  "                                                               

EEC_1A db "                      "Extended Error Code Unknown Media Type          "                                                                

EEC_1B db "                      "Extended Error Code Sector Not Found            "                                                                

EEC_1C db "                      "Extended Error Code Out of Paper                "                                                                 

EEC_1D db "                      "Extended Erroc Code Write Fault                 "                                                                

EEC_1E db "                      "Extended Error Code Read Fault                  "                                                                

EEC_1F db "                      "Extended Error Code General Failure             "                                                                 

EEC_20 db "                      "Extended Error Code sharing violation           "                                                                

EEC_21 db "                      "Extended Error Code Lock Violation              "                                                                

EEC_22 db "                      "Extended Error Code Invalid Disk change         "                                                                

EEC_23 db "                      "Extended Error Code FCB Unavailable             "                                                                 

EEC_24 db "                      "Extended Error Code Sharing Buffer overflow     "                                                                

EEC_26 db "                      "Extended Error Code Can't Complete File operation"                                                               

 EEC_32 db "                      "Extended Error Code Network Request Not Supported"                                                                

EEC_33 db "                      "Extended Error Code Remote Computer Not Listening                                                                

EEC_34 db "                      "Extended Error Code Duplicate Name on Netwirk    "                                                              

EEC_35 db "                      "Extended Error Code Network Name Not Found       "                                         

275页

EEC_36 db         "Extended Error Code        Network Busy"                                                   

EEC_37 db         "Extended Error Code        Network Device No Longer Exists"                                

EEC_38 db         "Extended Error Code        NetBIOS Command Limit  Exceeded"                                

EEC_39 db         "Extended Error Code        Network Adapter Error"                                          

EEC_3A db         "Extended Error Code        Incorrect Network Response"                                      

EEC_3B db         "Extended Error Code        Unexpected Network Error"                                       

EEC_3c db         "Extended Error code        Incompatible Remote Adapter"                                    

EEC_3D db         "Extended Error Code         Print Queue Full"                                               

 

EEC_3E db         "Extended Error Code         NOt Enough Room For Print File"                                  

EEC_3F db         "Extended Error Code         Print File Deleted"                                              

EEC_40 db         "Extended Error Code         Network Name Deleted"                                            

EEC_41 db         "Extended Error Code         Access Denied"                                                   

EEC_42 db         "Extended Error Code         Network Device Type Incorrect"                                   

EEC_43 db         "Extended Error Code         Network Name Not Found"                                          

EEC_44 db         "Extended Error Code         Network Name Limit Exceeded"                                     

EEC_45 db         "Extended Error Code         NetBIOS Session Limit Exceeded"                                  

EEC_46 db         "Extended Error Code         Sharing Temporarily Paused"                                      

EEC_47 db         "Extended Error Code         Network Request NOt Accepted"                                     

EEC_48   db       "Extended Error Code         Print/DiSk Redirection Paused"                                   

EEC_50 db         "Extended Error Code         File Already EXiSts"                                              

EEC_52 db         "Extended Error Code         Cannot Make Directory Entry"                                     

EEC_53 db         "Extended Error Code         Fail on int 24"                                                  

EEC_54 db         "Extended Error Code         Too Many Redirections"                                           

EEC_55 db         "Extended Error Code         Duplicate Redirection"                                           

EEC_56 db         "Extended Error Code         Invalid Password"                                                

EEC_57 db         "Extended Error Code         Invalid Parameter"                                               

EEC_58 db         "Extended Error Code         Network Data Fault"                                               

EEC_59 db         "Extended Error Code         Fn NOt supported By Network"                                     

EEC_5A db         "Extended Error Code         Req'd Sys. Comp. Not installed"                                   

EEC_Unknown db    "Error Class Code            Unknown"                                                         

ECC_01 db         "Error Class Code            out of Resource"                                                 

ECC_02 db         "Error Class Code            Temporary Situation"                                             

ECC_03 db         "Error Class Code            Authorization"                                                   

ECC_04 db         "Error Class Code            Internal"                                                        

ECC_05 db         "Error Class Code            Hardware Failure"                                                

ECC_06 db         "Error Class Code            System Failure"                                                  

ECC_07 db         "Error Class Code            Application Program Error"                                       

ECC_08 db         "Error Class Code            NOt Found"                                                       

ECC_09 db         "Error Class Code            Bad Format"                                                      

ECC_0A db         "Error Class Code            Locked"                                                           

ECC_0B db         "Error Class Code            Media"                                                           

ECC_0C db         "Error Class Code            Already Exists"                                                   

ECC_Unknown db    "Recommended Action          Unknown"                                                         

RAC_1 db          "Recommended Action          Retry Then Abort/Ignore"                                          

RAC_2   db        "Recommended Action          Delay & Retry Then Abort/Ignore"                                 

RAC_3 db          "Recommended Action          Get Correct Data From User"                                      

RAC_4 db          "Recommended Action          Abort Application with cleanup"                                  

RAC_5 db          "Recommended Action          Abort Without Cleanup Attempt"                                   

RAC_6 db          "Recommended Action          Ignore Error"                                                    

RAC_7 db          "Recommended Action          Correct Error Then Retry"                                       

RAC_Unknown db    "Locus                       Unknown"                                                         

LOCus_2 db        "Locus                       Block Device"                                                   

Locus_3 db        "Locus                       Network"                                                        

Locus_4 db        "Locus                       Serial Device"                                                  

Locus_5 db        "Locus                      Memory Related"                                                 

Locus_Unknown db                              "Unknown"                              

Bridgeline  db

Ignoreoption db        Ignore Error       

Retryoption   db       Retry Function Call

Terminateoption db     Terminate Program  

FailCalloption db      Fail Function Call 

BottomMenu db

276页

LINEWIDTH equ $-BottomMenu

ScreenSave db(LINEWIDTH*MAXLINES*2)dup(?)

MainTable dw Fn_00

dw Fn_01

dW Fn_02

dW Fn_03

dw Fn_04

dw Fn_05

dw Fn_06

dw Fn_07

dw Fn_08

dw Fn_09

dw Fn_0A

dw Fn_0B

dw Fn_0C

dw Fn_0D

dw Fn_0E

dw Fn_0F

dw Fn_10

dw Fn_11

dw Fn_12

dw Fn_13

dw Fn_14

dw Fn_15

dw Fn_16

dw Fn_17

dw UnknownFunction

dw Fn_19

dw Fn_1A

dw Fn_1B

dw Fn_1C

dw UnknownFunction

dw UnknownFunction

dw Fn_1F

dw UnknownFunction

dw Fn_21

dw Fn_22

dw Fn_23

dw Fn_24

dw Fn_25

dw Fn_26

dw Fn_27

dw Fn_28

dw Fn_29

dw Fn_2A

dW Fn_2B

dw Fn_2C

dw Fn_2D

dw Fn_2E

dw Fn_2F

dw Fn_30

dw Fn_31

dw Fn_32

dw -1

dw Fn_34

dw Fn_35

dw Fn_36

dw -1

dw Fn_38

dw Fn_39

dw Fn_3A

dw Fn_3B

dw Fn_3C

277页

dw Fn_3D

dw Fn_3E

dw Fn_3F

dw Fn_40

dw Fn_41

dw Fn_42

dW -1

dW -1

dw Fn_45

dw Fn_46

dw Fn_47

dw Fn_48

dw Fn_49

dw Fn_4A

dW -1

dw Fn_4C

dw Fn_4D

dw Fn_4E

dW Fn_4F

dw Fn_50

dw Fn_51

dW Fn_52

dw Fn_53

dW Fn_54

dw Fn_55

dw Fn_56

dW -1

dW -1

dW Fn_59

dW Fn_5A

dw Fn_5B

dw -1

dw -1

dw -1

dw -1

dw Fn_60

dw UnknownFunction

dw Fn_62

dw -1

dw Fn_64

dw Fn_65

dW -1

dw Fn_67

dw Fn_68

dw UnknownFunction

dw Fn_6A

dw UnknownFunction

dw Fn_6C

Table33 dw Fn_3300

dw Fn_3301

dw UnknownFunction

dW UnknOWnFunction

dw UnknownFunction

dw Fn_3305

Table37 dw Fn_3700

dw Fn_3701

dw Fn_3702

dw Fn_3703

Table43 dw Fn_4300

dw Fn_4301

Table44 dw Fn_4400

dW Fn_4401

278页

dw Fn_4402

dw Fn_4403

dw Fn_4404

dw Fn_4405

dw Fn_4406

dw Fn_4407

dw Fn_4408

dw Fn_4409

dW Fn_440A

dw Fn_440B

dw Fn_440C

dw Fn_440d

dw Fn_440E

dw Fn_440F

dw Fn_4410

dw Fn_4411

Table4B dw Fn_4B00

dW Fn_4B01

dw UnknownFunction

dw Fn_4b03

dw UnknownFunction

dw Fn_4B05

Table57 dw Fn_5700

dw Fn_5701

Table58 dw Fn_5800

dw Fn_5801

dw Fn_5802

dw Fn_5803

Table5c dw Fn_5C00

dw Fn_5C01

Table5D dw Fn_5D00

dw UnknownFunction

dw UnknownFunction

dw UnknownFunction

dw UnknownFunction

dw UnknownFunction

dw Fn_5D06

dw UnknownFunction

dw UnknownFunction

dw UnknownFunction

dW Fn_5D0A

Table5E dw Fn_5E00

dw Fn_5E01

dw Fn_5E02

dw Fn_5E03

Table5F dw UnknownFunction

dw UnknownFunction

dw Fn_5F02

dw Fn_5F03 .

dw Fn_5F04

Table63 dW Fn_6300

dw Fn_6301

dw Fn_6302

Table66 dw Fn_6600

dw UnknownFunction

dw Fn_6602

ECTable dW ErrorCOde00

dw ErrorCode01

dw ErrorCode02

dw ErrorCode03

dw ErrorCode04

dw ErrorCode05

279页

dw ErrorCode06

dw ErrorCode07

dw ErrorCode08

dw ErrorCode09

dw ErrorCode0A

dw ErrorCode0B

dw ErrorCode0C

dw UnknownErrorCode

dw UnknownErrorCode

dw ErrorCode0F

DiSkErrorTable dw DiSkErrOr0

dw DiskError1

dw DiskError2

dw DiskError3

dw DiSkError4

dw DiskError5

dw DiskError6

dw DiskError7

EEC_Table dw EEC_Unknown

dw EEC_01

dw EEC_02

dw EEC_03

dw EEC_04

dw EEC_05

dw EEC_06

dw EEC_07

dw EEC_08

dw EEC_09

dw EEC_0A

dw EEC_0B

dw EEC_0C

dW EEC_0D

dw EEC_Unknown

dw EEC_0F

dw EEC_10

dw EEC_11

dw EEC_12

dW EEC_13

dw EEC_14

dw EEC_15

dw EEC_16

dW EEC_17

dw EEC_18

dw EEC_19

dw EEC_1A

dw EEC_1B

dw EEC_1C

dw EEC_1D

dw EEC_1E

dw EEC_1F

dw EEC_20

dw EEC_21

dw EEC_22

dw EEC_23

dw EEC_24

dw EEC_Unknown

dw EEC_26

dw EEC_Unknown

dw EEC_UnknOwn

dw EEC_UnknOwn

dw EEC_Unknown

dw EEC_Unknown

280页

dw EEC_Unknown

dw EEC_UnknOwn

dw EEC_UnknOWn

dw EEC_Unknown

dw EEC_Unknown

dw EEC_Unknown

dw EEC_32

dw EEC_33

dw EEC_34

dw EEC_35

dw EEC_36

dw EEC_37

dw EEC_38

dw EEC_39

dw EEC_3A

dw EEC_3B

dw EEC_3C

dw EEC_3D

dw EEC_3E

dw EEC_3F

dw EEC_40

dw EEC_41

dw EEC_42

dw EEC_43

dw EEC_44

dw EEC_45

dW EEC_46

dw EEC_47

dw EEC_48

dw EEC_Unknown

dw EEC_Unknown

dw EEC_Unknown

dw EEC_Unknown

dw EEC_Unknown

dw EEC_UnknOWn

dw EEC_Unknown

dw EEC_50

dw EEC_Unknown

dW EEC_52

dw EEC_53

dw EEC_54

dw EEC_55

dw EEC_56

dw EEC_57

dw EEC_58

dw EEC_59

dw EEC_5A

ECC_Table dw ECC_Unknown

dw ECC_01

dw ECC_02

dw ECC_03

dw ECC_04

dw ECC_05

dw ECC_06

dw ECC_07

dw ECC_08

dw ECC_09

dw ECC_0A

dw ECC_0B

dw ECC_0C

RAC_Table dw RAC_Unknown

dw RAC_1

281页

dw RAC 2

dw RAC 3

dw RAC 4

dw RAC 5

dw RAC 6

dW RAC 7

Locus_Table dw Locus_Unknown

dw Locus_Unknown

dw Locus_2

dw Locus_3 .

dw Locus_4

dw Locus_5

criterr_data ends

; Stack structure in CritErr

CE_CallerStack struc

01dDS dw(?); DS on entry

01dES dw(?); ES on entry

01dBP dw(?); BP on entry

01dSI dw(?); SI on entry

01dDI dw(?); DI on entry

01dBX dw(?); BX on entry

01dCX dw(?); CX on entry

01dDX dw(?); DX on entry

Int21iP dw(?); Int 21 IP

Int21CS dw(?); Int 21 cs

Int21Flags dw(?); int 21 Flags

UsersAX dw(?); Caller's AX

UsersBX dw(?); Caller's BX

UsersCX dw(?); Caller's CX

UsersDX dw(?); Caller's DX

UsersSI dw(?); Caller's Si

UsersDI dw(?); Caller's Di

UsersBP dw(?); Caller's BP

UsersDS dw(?); Caller's DS

UsersES dw(?); Caller's ES

UsersIP dw(?); Caller's IP

UsersCS dw(?); Caller's CS

UsersFlags dw(?); Caller's Flags

CE_CallerStack ends

criterr_code segment

assume CS: criterr code

assume DS : nothing

assume ES : nothing

assume SS : nothing

CritErr proc

push DX ; Save registers

push CX

puSh BX

puSh DI

puSh si

push BP

push ES

pUSh DS

mov BX,seg criterr_data ; Set DS to local data

mov DS,BX

assume DS : Criterr data

mov IO_Type,AH ; Save special values

282页

mov DriveNumber,AL

mov ErrorCode,DI

mov DeviceDriverHeaderSegment,BP

mov DeviceDriverHeaderOffset,SI

mov BP,SP,Let BP point to stack structure

mov Line,offset DS:TOPMenu

mov Line+2,offset DS:UnknownFunction

mov AX,[BP-UsersAX]; Get caller's AX value

cmp AH,6CH ; Out of knOwn range?

jbe ValidFunction

jmp DumpRegistersIsle

ValidFunction:

 cmp AH,33H;Identify subfunction?

jne NOt_Fn33

jmp Fn33

NOt_Fn33:

cmp AH,37H

jne Not_Fn37

jmp Fn37

NOt_Fn37:

Cmp AH,43H

jne Not_Fn43

jmp Fn43

Not_Fn43:

cmp AH,44H

 jne NOt_Fn44

jmp fn44

NOt_Fn44:

cmp AH,4BH

jne NOt_Fn48

jmp Fn4B

NOt_Fn4B:

cmp AH,57H

jne NOt_Fn57

jmp Fn57

NOt_Fn57:

cmp AH,58H

jne NOt_Fn58

jmp Fn58

NOt_Fn58:

cmp AH,5CH

je Fn5C

cmp AH,5DH

je Fn5D

cmp AH,5EH

je Fn5E

cmp AH,5FH

je Fn5F

cmp AH,63H -

je Fn63

cmp AH,66H

je Fn66

Shl AH,1;Double the index

mov BL,AH ; Put in BX

xor BH,BH

mov AX,MainTable[BX]

jmp SetFunction

Fn66:

cmp AL,02H;Undefined?

ja DumpRegistersIsle

Shl AL,1

mov BL,AL

xOr BH,BH

283页

mov AX,Table66[BX]

 jmp SetFunction

Fn63:

 cmp AL,02H;Undefined?

 ja DumpRegistersIsle

Shl AL,1

mOv Si,AL

 XOr BH,BH

mov AX,Table63[BX]

jmp SetFunction

Fn5F:

cmp AL,04H;Undefined?

ja DumpRegistersIsle

Shl AL,1

mov BL,AL

xor BH,BH

mov AX,Table5F[BX]

 Jmp SetFunction

Fn5E:

cmp AL,03H;Undefined?

ja DumpRegistersIsle

Shl AL,1

mOv BL,AL

XOr BH,bH

mov AX,Table5E[BX]

jmp SetFunction

Fn5D:

cmp AL,0AH ; Undefined?

jbe Fn5D_1

DumpRegistersIsle:

jmp DumpRegisters

Fn5D_1:

Shl AL,1

mOv BL,AL

 xor BH,BH

mov AX,Table5D[BX]

jmp short SetFunction

Fn5C:

cmp AL,01H ; Undefined?

ja DumpRegisters

Shl AL,1

mOv BL,AL

xOr BH,BH

mov AX,Table5C[BX]

jmp short SetFunction

Fn58:

cmp AL,03H;Undefined?

ja DumpRegisters

shl AL,1

mOv BL,AL

xOr BH,BH

mov AX,Table58[BX]

jmp short SetFunction

Fn57:

cmp AL,01H ; Undefined?

ja DumpRegisters

Shl AL,1

mOv BL,AL

xOr BH,BH

mov AX,Table57[BX]

jmp short SetFunction

Fn4B:

cmp AL,05H ; Undefined?

284页

ja DumpRegisters

Shl AL,1

mOv BL,AL

xOr BH,BH

mov AX,Table4B[BX]

jmp short SetFunction

Fn44:

cmp AL,11H;Undefined?

ja DumpRegisters

Shl AL,1

mOv BL,AL

xOr BH,BH

mov AX,Table44[BX]

jmp short SetFunction

Fn43:

cmp AL,01H;Undefined?

ja DumpRegisters

Shl AL,1

mOv BL,AL

xOr BH,BH

mov AX,Table43[BX]

jmp short SetFunction

Fn37:

cmp AL,03H;Undefined?

ja DumpRegisters

shl AL,1

mOv BL,AL

xor BH,BH

mov AX,Table37[BX]

jmp short SetFunction

Fn33:

cmp AL_05H ; Undefined?

ja DumpRegisters

shl AL,1

mOv BL,AL

xor BH,BH

mov AX,Table33[BX]

SetFunction:

mov Line+2,AX

DumpRegisters:

mov BX,offset L2AX

mov AX,[BP.UsersAX]

call Fillword

mOv BX,offset L2BX

mov AX,[BP.UsersBX]

call FillWOrd

mov BX,offset L2CX

mov AX,[BP.UsersCX]

Call FillWOrd

mOv BX,Offset L2DX

mov AX,[BP.UsersDX]

call FillWord

mOv Line+4,offSet L2

mOv BX,Offset L3DI

mov AX,[BP.UsersDI]

call FillWOrd

mov BX,offset L3SI

mov AX,[BP.UsersSI]

call FillWOrd

mOv BX,offset L3BP

mov AX,[BP.UsersBP]

call FillWord

285页

mov BX,offset L3SP

mov AX,BP

add AX,size CE_CallerStack

call FillWord

mov Line+6,offset L3

mov BX,offset L4DS

mov AX,[SP.UsersDS]

call FillWord

mov BX,offset L4ES

mov AX,[BP.UsersES]

call FillWOrd

mov BX,Offset L4SS

mov AX,SS

call FillWord

mov Line+8,offset L4

mov BX,offset LSCS

mov AX,[BP.UsersCS]

call FillWord

mov BX,offset L5IP

mov AX,[BP.UsersIP]

call FillWord

mov BX,offset L5Flags

mov AX,[BP.UsersFlags]

teSt AX,0800H

jz OF_Clear

mOv byte ptr [BX],'O'

OF_Clear:

inc BX

teSt AX,0400H

jz DF_Clear

mOv byte ptr[BX],'D'

DF_Clear:

inc BX

teSt AX,0200H

jZ IF_Clear

mov byte ptr[BX],'I'

IF_Clear:

inc BX

test AX,0100H

ji TF_Clear

mov byte ptr[BX],'T'

TF_Clear:

inc BX

teSt AX,0080H

jz SF_Clear

mov byte ptr[BX],'S'

SF_Clear:

inc BX

teSt AX,0040H

jz ZF_Clear

mOv byte ptr[BX],'Z'

ZF_Clear:

inc BX

teSt AX,0010H

jz AF_Clear

mov byte ptr[BX],'A'

AF_Clear:

inc BX

test AX,0004H

jz PF_Clear

mov byte ptr[BX],'P'

286页

PF_Clear:

inc BX

teSt AX,0001H

jz CF_Clear

mov byte ptr[BX],'C'

CF_Clear:

mov Line+10,offset L5

mov AX,Offset UnknownErrorCode

mov BX,ErrorCode

xOr BH,BH

cmp BX,0FH

ja SetErrorCode

Shl BX,1

mov AX,ECTable[BX]

SetErrorCode:

mOv Line+12,AX

test IO_Type,80H

jz DiskError

mov AX,DeviceDriverHeaderSegment

mOv ES,AX

mov BX,DeviceDriverHeaderOffset

test wOrd ptr ES:[BX+4],8000H

jz UnknownDevice

push DS

push ES

mOv DS,AX

lea SI,[BX+10]

mov AX,seg criterr_data

mov ES,AX

mOv DI,offSet criterr_data:L7_Device

mov CX,8

cld

rep movsb

pop ES

pop DS

mOv Line+14,OffSet L7_Char

jmp short SetBridge

UnknownDeVice:

mOv Line+14,offset L7_UnknownChar

jmp short SetBridge

DiskError:

mov BL,IO_Type

and BL,7

xor BH,BH

Shl BX,1

mov BX,DiskErrorTable[BX]

mov Line+14,BX

mov AL,DriveNumber

add AL,'A'

mov [BX+DRIVE_OFFSET],AL

SetBridge:

mov Line+16,offset BridgeZLine

push DS

mov AH,59H

xor BX,BX

int 21H

pOp DS

mOv Line+18,Offset EEC_Unknown

cmp AX,5AH

ja NO_EEC

puSh BX

287页

mov BX,AX

shl BX,1

mOv AX,EEC_Table[BX]

pOp BX

mov Line+18,AX

No_EEC:

mov Line+20,offset ECC_Unknown

Cmp BH,0CH

ja NO_ECC

push BX

mov BL,BH

xor BH,BH

Shl BX,1

mov AX,ECC_Table[BX]

mov Line+20,AX

pop BX

NO_ECC:

mov Line+22,offSet RAC_Unknown

cmp BL,7

ja No_RAC

xor BH,BH

Shl BX,1

mOV AX,RAC_Table[BX]

mov Line+22,AX

NO_RAC:

mOv Line+24,offset Locus_Unknown

cmp CH,5

ja No_Locus

mov BL,CH

xOr BH,BH

Shl BX,1

mov AX,Locus_Table[BX]

mOv Line+24,AX

No_Locus:

mov Line+26,OffSet BridgeLine

cmp DOS_MajorVersion,2

ja NOtARF

jmD SetARF

NOtARF:

mov AL,IO_Type

and AL,38H

cmp AL,00H

jne Notoption0

mov Line+28,offset Terminateoption

mov Line+30,offset BottomMenu

mov MenuLines,15

mov Maximumoption,0

mov ReturnCOdes,offset Set__2_

jmp DrawScreen

NOtoption0:

cmp AL,08H

jne Notoption1

mov Line+28,offset Terminateoption

mov Line+30,offSet FaiLCalloption

mov Line+32,offset BottomMenu

mOv MenuLineS,16

mov Maximumoption,1

mov ReturnCodes,offset Set_23

jmp DrawScreen

NOtOptiOn1:

cmp AL,10H

288页

jne Notoption2

mov Line + 28,offset Retryoption

mov Line + 30,Offset Terminateoption

mov Line + 32,Offset BottomMenu

mov MenuLines,16

mov Maximumoption,1

mov ReturnCodes,offset Set_12_

jmp DrawScreen

Notoption2 :

cmp AL,18H

jne NotOption3

mov Line + 28,offset RetryOption

mov Line + 30,offset Terminateoption

mov Line + 32,offset FailCallOption

mov Line + 34,offset BottomMenu

mov MenuLines, 17

mov MaximumOption,2

mov ReturnCodes,offset Set_123

jmp DrawScreen

Notoption3 :

cmp AL,20H

jne Notoption4

mov Line + 28,offset Ignoreoption

mov Line + 30,offset TerminateOption

mov Line + 32,Offset BottomMenu

mov MenuLines,16

mov MaximumOption,1

mov   ReturnCodes,Offset Set0_2_

jmp DrawScreen

Notoption4 :

cmp AL,28H

jne Notoption5

mov Line + 28,offset Ignoreoption

mov Line + 30,Offset Terminateoption

mov Line + 32,offset FailCallOption

mov Line + 34,offset BottomMenu

mov MenuLines, 17

mov MaximumOption,2

mov ReturnCodes,offset Set0_23

jmp short DrawScreen

NotOption5 :

cmp AL,30H

jne NotOption6

SetARF :

mov Line + 28,offset IgnoreOption

mov Line + 30,offset RetryOption

mov Line + 32,offset TerminateOption

mov Line + 34,offset BottomMenu

mov MenuLines, 17

mov MaximumOption,2

mov ReturnCodes,offset Set012_

jmp short DrawScreen

Notoption6 :

mov Line + 28,offset Ignoreoption

mov Line + 36,offset Retryoption

mov Line + 32,offset Terminateoption

mov Line + 34,offset FailCallOption

mov Line + 36,offset BottomMenu

mov MenuLines, 18

mov Maximumoption,3

mov ReturnCodes,offset Set0123

289页

Drawscreen :

mov AX,0040H

mov ES,AX

mov AL ,ES:84H

sub AL,MenuLines

Shr AL,1

mov TopLine,AL

add AL,MenuLines

mov BottomLine,AL

mov AL,ES:4AH

 sub AL,LINEWIDTH

shr AL,1

mov LeftROw,AL

add AL,LINEWIDTH - 1

mov RightRow,AL

mov AH,0FH ; Get current display mode

int 10H

mov ActiveDisplaypage,BH

mov AH,3 ; Read cursor position and configuration

int 10

mov originalRow,DH

mov originalColumn,DL

mov SI,offset ScreenSave

mov DI,Offset Line

mov DH,TopLine

outerLoop :

mov DL,LeftRow

InnerLoop :

mov AH,2 ; Set cursor position

int 10H

mov AH,8 ; Read character and attribute

int 10H

mov [SI],AH

inc SI

mov [ SI ],AL

inc sI

mov AH,9 ; Write character and attribute

push SI

mov SI,DS:[ DI ]

mov AL,[SI ]

inc SI

mov  DS:[ DI ],SI

pop SI

mov BL,ATTRIBUTE

mov CX,1

int 10H

inc DL ; Next row

Cmp DL,RightRow

jbe innerLoop

inc DI

inc DI

inc DH ; Next line

cmp DH,BottomLine

jbe outerLoop

mov Currentoption,0

mov AH,2 ; Set cursor position

mov DH,TopLine

add DH,14

mov DL,LeftROw

inc DL

int 10H

mov AH,9 ; Write character and attribute

290页

mov AL,10H

mov BL,ATTRIBUTE

mov CX,1

int 10H

GetKey :

xor AH,AH ; Get keyboard character

int 16H

 or AL,AL ; Character Code 0?

jz Checkscancode

cmp AL,13 ; Return?

jne GetKey

jmp Return

CheckScanCode :

cmp AH,47H ; Home?

je  GoHome

cmp AH,48H ; CursorUp?

je GoUp

cmp AH,49H ; PageUp?

je Goup

cmp AH,4BH ; CursorLeft?

je GoUp

cmp AH,4DH ; CursorRight?

je GoDown

cmp AH,4FH ; End?

je GoEnd

 cmp AH,50H ; CursorDown?

je GoDown

cmp AH,51H ; PageDown?

jne GetKey

GoDown :

 mov AH,9 ; Write character and attribute

mov AL,' '

mov BL,ATTRIBUTE

mov CX,1

int 10H

mov AL,Currentoption

cmp AL,MaximumOption

jne MoveDown

xor AL,AL

MoveCur sor :

mov CurrentOption,AL

mov AH,2

mov BH,ActiveDisplaypage

mov DH,TopLine

add DH,14

add DH,AL

mov DL,LeftRow

inc DL

int 10H

mov AH,9 ; Write character and attribute

 mov AL,10H

mov BL,ATTRIBUTE

mov CX,1

int 10H

jmp GetKey

MoveDown :

inc AL

jmp MoveCursor

GoHome :

cmp Currentoption,0

je GetKey

 mov AH,9 ; Write character and attribute

mov  AL,' '

 

291页

mov BL,ATTRIBUTE

mov CX,1

int 10H

xor AL,Al

jmp MoveCursor

GoUp :

mov AH,9 ; Write character and attribute

mov  AL,' '

mov BL,ATTRIBUTE

mov CX,1

int 10H

mov AL,Currentoption

or AL , AL

jnz MoveUp

mov AL,MaximumOption

jmp MoveCursor

MoveUp :

dec AL

jmp MoveCursor

GoEnd :

mov AL,MaximumOption

cmp AL,CurrentOption

 jne Eraseoption

jmp GetKey

Eraseoption :

mov AH,9 ; Write character and attribute

mov   AL,' '

mov BL,ATTRIBUTE

 mov CX,1

int 10H

mov AL,Maximumoption

jmp MoveCursor

Return :

mov SI,offset ScreenSave

mov DH,TopLine

OuterLoop2 :

mov DL,LeftRow

InnerLoop2 :

mov AH,2 ; Set cursor position

int 10H

mov AH,9 ; Write character and attribute

mov BH,ActiveDisplaypage

mov BL,[ SI ]

inc SI

mov AL,[ SI ]

inc SI

mov CX,1

int 10H

inc DL , Next row

cmp DL,RightRow

jbe InnerLoop2

inc DI

inc DI

inc DH ; Next line

cmp DH,BottomLine

jbe outerLoop2

mov AH,2

mov BH,ActiveDisplaypage

mov DH,originalRow

mov DL,originalColumn

int 10H

mov AL,Currentoption

xor AH,AH

 

292页

mov BX,ReturnCodes

add BX,AX

mov AL,[ BX ]

pop DS ; Restore registers

pop ES

pop SP

pop SI

pop DI

pop BX

pop CX

pop DX

iret ; interrupt return

CritErr    endp

assume DS : criterr_data

FillWord proc near

xChg AH ,AL

call FillByte

xchg AH ,AL

call FillByte

ret

Fillword  endp

FillByte proc near

push CX

push AX

mov   CL,4

Shr AL,CL

call FillNibble

pop AX

Call FillNibble

pop CX

ret

FillByte    endp

FillNibble proc near

push AX

and AL,0FH

Cmp AL,9

jbe FillNibble_1

add AL,7

FillNibble_1 :

add AL,'0'

mov [BX ],AL

inc BX

pop AX

ret

FillNibble endp

assume DS : nothing

assume ES : nothing

assume SS : nothing

; Install the new critical error handler

_CritErrInit proc far

push DS ; Save old registers

push ES

push AX

push BX

push cx

push DX

mov AX,Seg criterr_data

mov DS,AX ; Set DS to local data

 

293页

assume DS: criterr_data

 mov AH,30H ; Get DOS version

int 21H

mov DOS_MajorVersion,AL

mov AH,35H ; Get old critical error handler address

mov AL,24H

int 21H

mov 01dCritErroffset,BX

mov 01dCritErrSegment,ES

mov AH,25H ; Set new critical error handler address

mov AL,24H

mov DX,seg criterr_code

mov DS,DX

mov DX,offset CS:CritErr

int 21H

pop DX ; Restore old registers

pop cx

pop BX

pop AX

pop ES

pop DS

ret  ; Return to Caller

_CritErrInit    endp

assume DS : nothing

; Reinstall the critical error handler (as after

; returning from a DOS shell)

_CritErrReInit proc far

push DS ; Save old registers

push AX

push DX

mov AH,25H ;  Set new critical error handler address

mov AL,24H

mov DX,seg criterr_code

mov DS,DX

mov DX,offSet CS:CritErr

int 21H

 pop DX ; Restore old registers

pop AX

pop DS

ret ; Return to caller

_CritErrReInit endp

; Uninstall the critical error handler (as before,

; invoking a DOS shell)

_CritErrUnInit proc far

push DS ; Save old registers

push AX

push DX

mov AX,seg criterr_data

mov DS,AX ; Set DS to local data

assume DS : criterr_data

mov AX,01dCritErroffset

mov DX,01dCritErrSegment

mov DS , DX

assume DS : nothing

294页

              mov AH,25H;   Set old critical error handler address

              mov AL,24H

                    int    21H

              pop DX;         Restore old registers

              pop AX

              pop DS

              ret;            Return to caller

    一CritErrUnInit endp

    public     CritErrInit

    public     CritErrReInit

    public     CritEPrUnInit

    criterr_code         ends

                  end

      我们已了解了有关中断的一些情况,并了解了TSR的激活方式,接下来让我们看看

    TSR的工作方式。

(未完待续)

转载于:https://www.cnblogs.com/Chaobs/p/3838525.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30575309/article/details/97538280

智能推荐

azkaban任务报错java.lang.RuntimeException: The root scratch dir: /tmp/hive_azkaban kettle 时间长报错-程序员宅基地

文章浏览阅读3.2k次。azkaban运行任务的时候失败报错如下:23-03-2016 08:16:14 CST analyzer-kafka2hdfs_new ERROR - Exception in thread "main" org.apache.hive.service.cli.HiveSQLException: java.lang.RuntimeException: The root scratch d_azkaban kettle 时间长报错

PHP生成迅雷、快车、旋风等软件的下载链接代码实例-程序员宅基地

文章浏览阅读131次。<?php function Download() { $urlodd=explode('//',$_POST["url"],2);//把链接分成2段,//前面是第一段,后面的是第二段 $head=strtolower($urlodd[0]);//PHP对大小写敏感,先统一转换成小写,不然 出现HtTp:或者ThUNDER:这种怪异的写法不好处...

创建带有UTF-8 的声明的XMLDocument_xmlnewdoc utf-8-程序员宅基地

文章浏览阅读4.6k次。class Program { static void Main(string[] args) { // Create and load the XML document. XmlDocument doc = new XmlDocument(); string xmlString = "_xmlnewdoc utf-8

Jquery 多选下拉列表插件jquery multiselect-程序员宅基地

文章浏览阅读286次。有一个多选的需求,在网上找到了这个插件:multiselecthttps://github.com/ehynds/jquery-ui-multiselect-widgetcsdn博客上有这个插件的介绍,不少童鞋都问了这么个问题,怎么获取选中的值?真是个好问题,因为我在看demo的时候也发现了这个问题,呵呵!先简单说说这个插件: jquery-multisel..._multiselect 多级 多选插件 checkbox

解决android studio打包后安装APK提示“签名不一致,该应用可能已被修改。“_签名不一致该应用可能已被修改-程序员宅基地

文章浏览阅读8.4k次,点赞5次,收藏15次。现象解决办法修改applicationId名_签名不一致该应用可能已被修改

PHP用户缓存APCU_php apcu 100%-程序员宅基地

文章浏览阅读6.1k次。故事APCu 是老牌 PHP 字节码和对象缓存 缓存器 APC 的分支,具体由来还得讲个故事。首先提一下,PHP 如果公用多个缓存器是会冲突的,例如同样都是字节码缓存器,OPcache 和 eAccelerate 同时安装就会起冲突甚至报错;而 XCache 同时有字节码缓存器和对象缓存,和 OPCache 共存也是会起冲突的。在 PHP 5.5 之前是没有 OPcache 这个缓存器_php apcu 100%

随便推点

第一范式、第二范式、第三范式、BCNF(BC范式)-程序员宅基地

文章浏览阅读7.6k次,点赞11次,收藏37次。范式原理笔记数据库关系数据理论----范式范式原理笔记什么是(范式)---范式介绍范式发展1、第一范式2、第二范式3、第三范式4、BCNF(扩展第三范式)什么是(范式)—范式介绍官方介绍,数据库中的关系是要满足一定要求的,满足不同程度要求的为不同范式。满足最低要求的叫第一范式,简称1NF;在第一范式中满足进一步要求的为第二范式,其余的一次类推。还不懂?那么简单来说范式是一种标准,也就是你设计表结构是要符合规范。就好像是你装修自己的房子,你按照的标准越高,那么你的房子就更加的牢固安全。所谓“第几范_第一范式

【openresty】API disabled in the context of init_worker_by_lua_api disabled in the current context-程序员宅基地

文章浏览阅读4.9k次。在调用init.lua初始化的过程中,我调用了mysql数据库接口初始化数据,然后就提示了此错误:2020/06/28 19:56:40 [error] 24673#24673: *7 [lua] init.lua:2: init , context: init_worker_by_lua*2020/06/28 19:56:40 [error] 24673#24673: *7 [lua] data.lua:11: load(): context: init_worker_by_lua*2020/0_api disabled in the current context

openlayers6【八】地图覆盖物overlay详解_ol.overlay-程序员宅基地

文章浏览阅读5k次,点赞4次,收藏16次。文章目录1. overlay 简述2. overlay 属性2. overlay 事件4. overlay 方法5. overlay 实例5.1 overlay 实现 windowInfo 弹窗5.2 overlay 实现 label标注信息5.3 overlay 实现 text文本信息1. overlay 简述overlay是覆盖物的意思,顾名思义就是在地图上以另外一种形式浮现在地图上,这里很多同学会跟图层layers搞混淆,主要是放置一些和地图位置相关的元素,常见的地图覆盖物为这三种类型,如:win_ol.overlay

matlab 广义互相关,广义互相关求时延的问题-程序员宅基地

文章浏览阅读708次。clear all%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%获得语音文件%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[x,fs,nbits]=wavread('bluesky3.wav'); %%%%%%打开wav文件%fs=8000%nbits=16x=x/max(abs(x)); %%%%%幅度..._matlab中广义互相关scot求时延

搜索关键词采集YouTube视频字幕-程序员宅基地

文章浏览阅读2.5k次,点赞2次,收藏12次。使用python采集YouTube视频字幕本篇博客纯干货!!!最近接到leader安排的采集任务,抓取采集世界上最大的视频共享网站YouTube的视频字幕。分析目标网站,开始抓包当我打开视频链接点击显示字幕按钮时,通过浏览器抓取到timedtext这样的一个请求,而返回的内容正式我想要的数据——每个时间点的字幕。...

无语!35 岁华人程序员涉嫌诈骗 150 万美元抗疫贷款,在美国遭 FBI 逮捕-程序员宅基地

文章浏览阅读1.6k次。(给程序员的那些事加星标)有个华人程序员????了最近,有一个华人程序员在网上「火了」,负面的那种火。????5 月 22 日,美国司法部官网公开了一份刑事起诉书,一位软件工程师涉嫌 1...