Top Document: comp.os.msdos.programmer FAQ part 4/5 Previous Document: Next Document: See reader questions & answers on this topic! - Help others by sharing your knowledge Interrupt service routines can be tricky, because you have to do some things differently from "normal" programs. If you make a mistake, debugging is a pain because the symptoms may not point at what's wrong. Your machine may lock up or behave erratically, or just about anything else can happen. Here are some things to look for. (See <Q:08.06> [How can I write a TSR (terminate-stay-resident utility)?] for general techniques that may prevent a problem.) First, did you fail to set up the registers at the start of your routine? When your routine begins executing, you can count on having CS point to your code segment and SS:SP point to some valid stack (of unknown length), and that's it. In particular, an interrupt service routine must set DS to DGROUP before accessing any data in its data segments. (If you're writing in a high-level language, the compiler may generate this code for you automatically; check your compiler manual. For instance, in Borland and Microsoft C, give your function the "interrupt" attribute.) Did you remember to turn off stack checking when compiling your interrupt server and any functions it calls? The stack during the interrupt is not where the stack-checking code expects it to be. (Caution: Some third-party libraries have stack checking compiled in, so you can't call them from your interrupt service routine.) Next, are you calling any DOS functions (INT 21, 25, or 26) in your routine? DOS is not re-entrant. This means that if your interrupt happens to be triggered while the CPU is executing a DOS function, calling another DOS function will wreak havoc. (Some DOS functions are fully re-entrant, as noted in Ralf Brown's interrupt list (<Q:02.03> [What and where is Ralf Brown's interrupt list?]). Also, your program can test, in a way too complicated to present here, when it's safe to call non-re-entrant DOS functions. See INT 28, INT 21 AH=34, and INT 21 AX=5D06 or 5D0B; and consult {Undocumented DOS} by Andrew Schulman. Your program must read both the "InDOS flag" and the "critical error flag".) Is a function in your language library causing trouble? Does it depend on some initializations done at program startup that is no longer available when the interrupt executes? Does it call DOS (see preceding paragraph)? For example, in both Borland and Microsoft C the memory- allocation functions (malloc(), etc..) call DOS functions and also depend on setups that they can't get at from inside an interrupt; so do the standard I/O functions like scanf() and printf(). Many other library functions have the same problem, so you can't use them inside an interrupt function without special precautions. Is your routine simply taking too long? This can be a problem if you're hooking on to the timer interrupt, INT 1C or INT 8. That interrupt expects to be called about every 55 ms, which is 18.2 times a second. Therefore your routine, plus any others hooked to the same interrupts, must execute in less than 55 ms. If they use even a substantial fraction of that time, you'll see significant slowdowns of your foreground program. A good discussion is downloadable as: <http://www.simtel.net/pub/pd/46893.html> Did you forget to restore all registers at the end of your routine? Reader, Morten Welinder, notes that programmers of interrupt procedures in Borland/Turbo Pascal 7.0 should be aware that the high words or the 32-bit registers are not saved automatically and that the run-time library may trash them if, e.g., you use longint operations. The easy way around this is to do "Test8086 := 0;" before installing the interrupt handler. Did you chain improperly to the original interrupt? You need to restore the stack to the way it was upon entry to your routine, then do a far jump (not call) to the original interrupt service routine. (The process is a little different in high-level languages.) User Contributions:Top Document: comp.os.msdos.programmer FAQ part 4/5 Previous Document: Next Document: Part1 - Part2 - Part3 - Part4 - Part5 - Single Page [ Usenet FAQs | Web FAQs | Documents | RFC Index ] Send corrections/additions to the FAQ Maintainer: jeffrey@carlyle.org (Jeffrey Carlyle)
Last Update March 27 2014 @ 02:11 PM
|
Comment about this article, ask questions, or add new information about this topic: