4
votes

Can I call interrupt from within interrupt service routine in freestanding x686 environment?

So can one do the following:

isr:
    pusha
    call doSomething
    int 21h
    popa
iret

If it's possible, then do these nested interrupts have any significant cave ins?

2

2 Answers

3
votes

While the processor places no fundamental restrictions on nesting interrupts, MS-DOS and BIOS services are not reentrant. That is, they're generally not safe to call during a hardware interrupt as the interrupt may occur while CPU is already executing an MS-DOS or BIOS functions.

To use MS-DOS and BIOS services from an hardware interrupt service routine, there are a number of steps you can take to ensure that they can be used safely. What you need to do is fairly complex, amongst other things you need monitor the InDos flag and hook other interrupts, so I'll just point you to the section on reentrency in the The Art of Assembly Language Programming. It does a pretty good job of covering all the details.

Here's an excerpt from that section. This is just part of what you might need to do:

MS-DOS provides a special one-byte flag (InDOS) that contains a zero if DOS is currently active and a non-zero value if DOS is already processing an application request. By testing the InDOS flag your TSR can determine if it can safely make a DOS call. If this flag is zero, you can always make the DOS call. If this flag contains one, you may not be able to make the DOS call. MS-DOS provides a function call, Get InDOS Flag Address, that returns the address of the InDOS flag. To use this function, load ah with 34h and call DOS. DOS will return the address of the InDOS flag in es:bx. If you save this address, your resident programs will be able to test the InDOS flag to see if DOS is active.

Actually, there are two flags you should test, the InDOS flag and the critical error flag (criterr). Both of these flags should contain zero before you call DOS from a TSR. In DOS version 3.1 and later, the critical error flag appears in the byte just before the InDOS flag.

So what should you do if these flags aren't both zero? It's easy enough to say "hey, come back and do this stuff later when MS-DOS returns back to the user program." But how do you do this? For example, if a keyboard interrupt activates your TSR and you pass control on to the real keyboard handler because DOS is busy, you can't expect your TSR to be magically restarted later on when DOS is no longer active.

The trick is to patch your TSR into the timer interrupt as well as the keyboard interrupt. [...]

2
votes

An interrupt call is just analogous to a regular call with flags pushed. And what iret does is it returns and pops the flags. So, yes, interrupts can be called recursively. Actually calling an interrupt in another interrupt handler happens all the time due to hardware interrupts running continuously on the system, unless you disable them of course.

Hardware interrupts have further restrictions, and usually are not called while inside the same handler before it finishes processing. Interrupt handlers notify the hardware to provide new interrupts by signaling the interrupt controller.