Chaining Interrupts Using MASM
ID: Q104674
|
The information in this article applies to:
-
Microsoft Macro Assembler for MS-DOS, versions 6.0, 6.0a, 6.0b, 6.1, 6.1a, 6.11
SUMMARY
Interrupt handlers in assembler may either stand alone or use the old
interrupt handler for functions not covered by the new handler. Using
the old handler is called chaining, and is needed for many MS-DOS and
BIOS interrupts. A handler that does not chain uses an IRET (interrupt
return) statement rather than a normal return statement (RET, RETN,
RETF).
There are two ways to chain to an old interrupt handler:
- Jumps are used when the chain is the last thing in your new
handler, and in this case your handler's IRET statement is never
executed.
-or-
- Calling the old handler is done when you need to return to your
handler for further processing after the original handler has
finished. In this case, your return statement is very important.
The difference between IRET and RET is that IRET pops an extra 2
bytes off the stack (the flags register is popped). An interrupt call
always pushes the flags onto the stack before pushing on the far
return address. In general, hardware interrupt handlers use an IRET
statement while software interrupt handlers use a RETF 2 (far return)
statement.
MORE INFORMATION
Interrupt handlers that chain to Interrupt 21h are special cases
because they always chain to the old interrupt. If they didn't chain,
they would need to provide replacements for all of the MS-DOS
functions, which would essentially involve rewriting the operating
system. If the chaining is done at the end of the new handler using a
JMP instruction, no special return is needed. In fact, the return
statement in the new handler is never executed.
Most software interrupts, including interrupt 21h functions, set the
flags to particular values, and those values are used as part of the
returned information from the handler. The original values are not
restored from the stack when the interrupt returns. IRET is not used.
Instead, a RETF 2 statement is used to do a far return and pop 2 bytes
off the stack.
If an Interrupt 21h handler chains to the original handler using a
CALL statement, it must not use IRET. The system will probably hang if
you have an IRET in the handler because some functions may be called
repeatedly by MS-DOS until a certain flag is returned. Executing IRET
restores the prior values of the flags and destroys any values set by
the Interrupt 21h call. Thus, it appears as if the flags never get
set, so an infinite loop results.
If the code after the CALL in your Interrupt 21h handler modifies the
flags, you may need to put a PUSHF ... POPF around that code. The
sample code below creates a "do-nothing" replacement for Interrupt 21h
and illustrates these points. If the "RETF 2" is replaced with an
IRET, a system hang will result.
Sample Code
; assembly options needed: none
.MODEL tiny, pascal, os_dos
.STACK
.CODE
.STARTUP
FPFUNC TYPEDEF FAR PTR
Old_INT_21 FPFUNC ? ; Data in code segment
; holds old interrupt address.
jmp SetNewInterrupt ; Skip the new handler.
New_INT_21 PROC FAR
; May do some work here.
; If nothing needs to be done after the old
; handler is called, a jump can be used as follows:
; jmp cs:Old_INT_21
; If the jump is used, the remaining code is not executed.
cli ; Interrupts off.
pushf
call cs:Old_INT_21 ; Call original handler.
pushf
; Chance to do other things.
popf
retf 2
New_INT_21 ENDP
SetNewInterrupt PROC
mov ax, 3521h
int 21h ; Get addr of Interrupt 21 handler.
mov WORD PTR cs:Old_INT_21[0], bx ; Save offset of 21 handler.
mov WORD PTR cs:Old_INT_21[2], es ; Save seg of 21 handler.
push ds
mov ax, cs
mov ds, ax ; Seg of new handler into ds.
mov dx, OFFSET New_INT_21 ; Offset of new handler into dx.
mov ax, 2521h
int 21h ; Install new 21h handler.
pop ds ; Restore ds.
; calc paragraphs to retain
mov dx, OFFSET SetNewInterrupt
mov cl, 4
shr dx, cl
inc dx
mov ax, 3100h ; Make new handler resident.
int 21h
.EXIT
SetNewInterrupt ENDP
END
Additional query words:
6.00 6.00a 6.00b 6.10
Keywords :
Version : :6.0,6.0a,6.0b,6.1,6.11,6.1a
Platform :
Issue type :