The __interrupt keyword indicates that the function is an interrupt handler. The compiler generates appropriate entry and exit sequences for the interrupt-handling function, including saving and restoring all registers and executing an IRET instruction to return.
When an interrupt function is entered, the DS register is initialized to the default (near) data segment. This allows access to global variables from within an interrupt function.
In addition, all registers (except SS) are saved on the stack. These registers can be accessed within the function by declaring a function-parameter list containing a formal parameter for each saved register. The following example illustrates such a declaration:
void __interrupt __far int_handler(
unsigned _es, unsigned _ds,
unsigned _di, unsigned _si,
unsigned _bp, unsigned _sp,
unsigned _bx, unsigned _dx,
unsigned _cx, unsigned _ax,
unsigned _ip, unsigned _cs,
unsigned flags )
Restrictions on Interrupt Functions
An interrupt function must be far. Programs compiled with the small or compact memory model must explicitly declare interrupt functions with the __far keyword.
Interrupt functions must observe the __cdecl calling convention. Therefore,
the only calling convention keyword that can be used in combination with
__interrupt is __cdecl.
Functions declared with the __interrupt keyword cannot also be declared with the __saveregs keyword.
Considerations When Using __interrupt
When an interrupt function is called by an INT instruction, the interrupt enable flag is cleared. This means that no further interrupts (including keyboard, time-of-day, and other crucial interrupts) are processed until the interrupt function returns.
If an interrupt function needs to do significant processing, it should call the _enable function to reset the interrupt-enable flag.
Interrupt functions must obey special rules because they are potentially reentrant (that is, the function can be entered more than once before the first return is executed). When designing an interrupt-handling function, consider the following guidelines:
If the function does not use the _enable function to set the interrupt flag, important interrupts may be ignored. This can result in such undesirable effects as lost keystrokes and inaccurate real-time clocks.
If the function uses the _enable function to set the interrupt flag, another interrupt of the same sort may take place. To make sure that the interrupt handler takes this into account, serialize access to all objects that are not automatic or accessed on the free store using an automatic pointer.