Interrupt flag

(Redirected from IF (x86 flag))

The Interrupt flag (IF) is a flag bit in the CPU's FLAGS register, which determines whether or not the (CPU) will respond immediately to maskable hardware interrupts.[1] If the flag is set to 1 maskable interrupts are enabled. If reset (set to 0) such interrupts will be disabled until interrupts are enabled. The Interrupt flag does not affect the handling of non-maskable interrupts (NMIs) or software interrupts generated by the INT instruction.

Setting and clearing

edit

In a system using x86 architecture, the instructions CLI (Clear Interrupt) and STI (Set Interrupt). The POPF (Pop Flags) removes a word from the stack into the FLAGS register, which may result in the Interrupt flag being set or cleared based on the bit in the FLAGS register from the top of the stack.[1]

Privilege level

edit

In systems that support privileged mode, only privileged applications (usually the OS kernel) may modify the Interrupt flag. In an x86 system this only applies to protected mode code (Real mode code may always modify the Interrupt flag). CLI and STI are privileged instructions, which cause a general protection fault if an unprivileged application attempts to execute them. The POPF instruction will not modify the Interrupt flag if the application is unprivileged.

Old DOS programs

edit

Some old DOS programs that use a protected mode DOS extender and install their own interrupt handlers (usually games) use the CLI instruction in the handlers to disable interrupts and either POPF (after a corresponding PUSHF) or IRET (which restores the flags from the stack as part of its effects) to restore it. This works if the program was started in real mode, but causes problems when such programs are run in a DPMI-based container on modern operating systems (such as NTVDM under Windows NT or later). Since CLI is a privileged instruction, it triggers a fault into the operating system when the program attempts to use it. The OS then typically stops delivering interrupts to the program until the program executes STI (which would cause another fault). However, the POPF instruction is not privileged and simply fails silently to restore the IF. The result is that the OS stops delivering interrupts to the program, which then hangs. DOS programs that do not use a protected mode extender do not suffer from this problem, as they execute in V86 mode where POPF does trigger a fault.

There are few satisfactory resolutions to this issue. It is usually not possible to modify the program, as source code is typically not available and there is no room in the instruction stream to introduce an STI without massive editing at the assembly level. Removing CLI's from the program or causing the V86 host to ignore CLI completely might cause other bugs if the guest's interrupt handlers aren't designed to be re-entrant (though when executed on a modern processor, they typically execute fast enough to avoid overlapping of interrupts).

Disabling interrupts

edit

In the x86 instruction set CLI is commonly used as a synchronization mechanism in uniprocessor systems. For example, a CLI is used in operating systems to disable interrupts so kernel code (typically a driver) can avoid race conditions within an interrupt handler. This is necessary when modifying multiple associated data structures without interruption.

Enabling Interrupts

edit

The STI of the x86 instruction set enables interrupts by setting the IF.

In some implementations of the instruction which enables interrupts, interrupts are not enabled until after the next instruction. In this case the sequence of enabling interrupts immediately followed by disabling interrupts results in interrupts not being recognized.

Multiprocessor Considerations

edit

The Interrupt flag only affects a single processor. In multiprocessor systems an interrupt handler must use other synchronization mechanisms such as locks.

See also

edit

References

edit
  1. ^ a b "Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference Manual" (PDF). Retrieved 2007-07-13.
edit