📄 except.doc
字号:
USER-GENERATED EXCEPTIONS IN GENERAL------------------------------------MS-DOS users can generate exceptions by means of two separatemechanisms, Ctrl-C and Ctrl-Break. Although these are often treatedthe same, they are actually handled in subtly different manners. Thedifference in the way these are processed allows a great deal offlexibility in allowing users to interrupt an executing program.When a program is executed, the Ctrl-C Interrupt 23h is set up topoint to a default error handler. This handler is called whenever aCtrl-C character is detected in the keyboard input buffer. When aprogram terminates in any way, MS-DOS resets the Interrupt 23h vectorto its default state. Note that the Ctrl-C character in the inputbuffer is only recognized - and an Interrupt 23h generated - whenretrieving characters from the buffer and if BREAK ON is set.The Ctrl-Break Interrupt 1Bh works somewhat differently, thoughusually in concert with Interrupt 23h. Whenever the ROM BIOS detectsthe Ctrl-Break key combination, the keyboard buffer is flushed and aCtrl-C key combination is stuffed in place of the previous contents.This Ctrl-C will later be detected and processed by Interrupt 23h.Ctrl-Break processing therefore offers more immediate response thanCtrl-C processing if the default action is overridden.Several caveats are in order here, however. First is the fact that,unlike Interrupt 23h, MS-DOS does not restore the default state ofInterrupt 1Bh upon program termination. Second is that while Ctrl-Cprocessing is standardized among the various machines utilizing bothMS-DOS and PC-DOS, Ctrl-Break processing is much less standardized.Finally, since processing either ultimately relies on trappingCtrl-C, either may be ignored for a long period because of the waythat Ctrl-C is detected.HANDLING USER-GENERATED EXCEPTIONS----------------------------------DOS's default Ctrl-C handler is triggered whenever the Ctrl-Ccharacter is detected in the input buffer. DOS's response is tosimply close all files which were opened using handle functions andto terminate the program. The limitations of this approach and thedesirability of providing your own exception processing is obvious.An equally obvious solution to the default Ctrl-C handler's problemsis to explicitly do your own Ctrl-C exception processing. CCTRAP.ASMinstalls and de-installs you own customized exception handler. Notethat the code is written to accept the address of a function specifiedwith an explicit segment and offset.Also note that an explicit de-installation function is provideddespite the fact that DOS restores the default Int 23h vector uponprogram termination. The reason this is provided is that you shouldalways de-install a Ctrl-C interrupt trap before you spawn a childprocess. Within your program, if you need to spawn such a processthrough any mechanism other than spawning a subordinate shell (moreon this in a second), you should explicitly de-install your interrupthandlers and re-install them when the subordinate process returns. Asnoted, this is unnecessary when the subordinate process is a DOSshell such as COMMAND.COM, since the shell will reset the interruptsto their defaults during execution.Ctrl-Break processing is much more problematical, though potentiallymore powerful. The first problem to deal with is how to assure thatthe default Int 1Bh Ctrl-Break handler will be restored upon programtermination. The de-installation function therefore becomes mandatoryin this context rather than optional as in the case of the Int 23hhandler. CBTRAP.ASM shows a sample Ctrl-Break handler. Since Ctrl-Breakprocessing is much less standardized than Ctrl-C processing, thesafest way to deal with it is to simply set a flag, "cbrcvd", whichinforms your program that a Ctrl-Break has been received. Yourprogram may then poll this flag and take appropriate actions at"safe" times within your program.WHERE THE CARET-C COMES FROM----------------------------There's still nothing new here and nothing to prevent the ugly "^C"being printed to the screen. This is because it is actually printedby the BIOS during Int 9 processing, long before DOS ever sees it.What this means is that even though the code in CCTRAP.ASM andCBTRAP.ASM is fine, it still only provides a framework for solvingour problem.TRAPFLAG.ASM is the final trick to banish the "^C". The actual ISRhas to muck around quite a bit with the keyboard hardware, as is tobe expected of an Int 09h replacement. Whenever a Ctrl-C or Ctrl-Break is detected, it is trapped, and our exception handler called inplace of the original Int 09h handler, after discarding the trappedkey codes.Referring to TRAPFLAG.ASM, note that since I need to trap both Ctrl-Cand Ctrl-Break, I adopt the flag approach introduced in CBTRAP.ASMfor dealing with both Ctrl-C and Ctrl-Break processing. Now, ratherthan supplying an explicit exception vector, I merely set a globalflag to inform me if either exception has occurred and accept theresponsibility of processing the exceptions within the body of myprogram. I've added an extra bit of versatility here by postingdifferent non-zero values to the flag, "ccrcvd" depending on whetherthe exception was a Ctrl-C or Ctrl-Break.TRAPDEMO.C is a short C program demonstrating the use of the combinedCtrl-C/Ctrl-Break handler. Using this approach, your carefullycrafted screens need never more be cluttered with the "^C" uglies.SYSTEM-GENERATED EXCEPTIONS---------------------------It's usually desirable, in any professional-looking program, toexplicitly trap the Int 24h critical error interrupt to processsystem-generated exceptions. CERRINST.ASM is a portable criticalerror handler installation program functionally equivalent to the[_]hardxxx() package in Borland C++ and Microsoft C++ compilers, andthe ceror_xxx() package in Zortech C++.It's obvious that writing code to intercept DOS critical errorexceptions is just as simple as intercepting Ctrl-C or Ctrl-Breakexceptions. The real challenge in writing critical error handlers isin interpretation of the nature of the exception.The critical error handler requires more information in order todecide what action to take than does a Ctrl-C handler. All of thisinformation is passed in the CPU's registers. Just like a typicalcompiler vendor's critical error handler, CERRINST.ASM will simplypass these registers and leave their interpretation to you. InCERRINST.ASM, the information required for intelligent critical errorprocessing is posted in 4 global variables, cedevdvr, cetype,ceerror, and cereturn.Next you need to determine what your program requires of a criticalerror handler. CERRTRAP.ASM is a skeletal, yet robust critical errorfunction which may be called from the handler in CERRINST.ASM.CERRTRAP.ASM assumes you have set up the following specific errorhandlers in the global variables provided:FAT error (*FAT_err)();Disk read error (*read_err)()Disk write error (*write_err)()Terminal error (*term_err)(),Printer out of paper (*no_paper)(),All other errors (*fixup_ret)(),In the case of an unrecognized error, fixup_ret() is called. A simpleskeleton for this function would be:#include <dos.h> /* for _osmajor */extern int exerr; /* DOS extended error posted by CERRTRAP.ASM */extern int rmvbl; /* removable media flag posted by CERRTRAP.ASM */extern int locus; /* extended error locus posted by CERRTRAP.ASM */extern int class; /* extended error class posted by CERRTRAP.ASM */extern int suggest; /* suggested action posted by CERRTRAP.ASM */int fixup_ret(void){ if (2 < _osmajor) { /* analyze DOS extended error information */ return appropriate_error_code; } /* cleanup */ return 2; /* abort */}In customizing your specific critical error handler functions, thereare several important restrictions to keep in mind. The first is thatno DOS system services may be requested other than Interrupt 21hfunctions 01h-0Ch (character I/O), 30h (get DOS version number), and59h (get extended error information). All registers except AL must bepreserved since DOS sets them up for processing Retry returns priorto invoking the critical error interrupt.Finally, the handler must return with an IRET instruction, passing areturn code in AL to tell DOS what to do next. The available codesand their actions under various DOS versions are: 0 - Ignore 1 - Retry 2 - Abort 3 - Fail (DOS 3.3 and later)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -