Search code examples
exceptionx86interruptinterrupt-handling

What's the difference between Software-Generated Interrupt and Software-Generated Exception?


I am reading the Intel Manual 3A Chapter 6 Interrupt and Exception Handling.

Interrupt and Exception have 3 sources respectively.

For Software-Generated Interrupt, it says:

The INT n instruction permits interrupts to be generated from within software by supplying an interrupt vector number as an operand. For example, the INT 35 instruction forces an implicit call to the interrupt handler for interrupt 35. Any of the interrupt vectors from 0 to 255 can be used as a parameter in this instruction. If the processor’s predefined NMI vector is used, however, the response of the processor will not be the same as it would be from an NMI interrupt generated in the normal manner. If vector number 2 (the NMI vector) is used in this instruction, the NMI interrupt handler is called, but the processor’s NMI-handling hardware is not activated. Interrupts generated in software with the INT n instruction cannot be masked by the IF flag in the EFLAGS register.

For Software-Generated Exceptions, it says:

The INTO, INT 3, and BOUND instructions permit exceptions to be generated in software. These instructions allow checks for exception conditions to be performed at points in the instruction stream. For example, INT 3 causes a breakpoint exception to be generated. The INT n instruction can be used to emulate exceptions in software; but there is a limitation. If INT n provides a vector for one of the architecturally-defined exceptions, the processor generates an interrupt to the correct vector (to access the exception handler) but does not push an error code on the stack. This is true even if the associated hardware-generated exception normally produces an error code. The exception handler will still attempt to pop an error code from the stack while handling the exception. Because no error code was pushed, the handler will pop off and discard the EIP instead (in place of the missing error code). This sends the return to the wrong location.

So, what's the difference? Seems both leverage the int n instruction. How can I tell whether it generates an exception or an interrupt in a piece of assembly code?


Solution

  • In the x86 architecture an exception is handled as an interrupt, nominally with an interrupt handler.
    So interrupts and exceptions are terms that overlaps, the latter are a kind of the former.

    Interrupt numbers from 0 to 31 are reserved for CPU exceptions, for example interrupt number 0 is the #DE (Divide error), interrupt number 13 is the #GP (General Protection).

    When the CPU detects a condition that should rise an exception (like an access to a non present page) it performs a series of tasks.

    First it pushes an error code if needed, some exceptions (like #PF and #GP) do, some (like #DE) don't.
    The Section 6.15 of the Intel manual 3 lists all the exceptions with their eventual error code.

    Secondly it "calls" the appropriate interrupt handler which is like a far call but with EFLAGS pushed on the stack.

    int n does only the second step, it calls an interrupt but doesn't push any error code as there is no error condition in the hardware in the first place (and because int n was there before the concept of error codes).
    So it can be used to emulate exceptions, the software has to eventually push an appropriate error code.

    When you see int n in the code, it is never an exception. It is an interrupt, that eventually is used to steer the control flow into a particular OS exception handler.


    Trivia: int3 (with no space) is special because it is encoded as CC which is only one byte (normal int n is CD imm8). This is useful for debugging, since the debugger can put it anywhere in the code segment.
    into only generates the #OF exception if OF = 1.