Opcode Instruction Clocks Description CC INT 3 33 Interrupt 3--trap to debugger CC INT 3 pm=59 Interrupt 3--Protected Mode, same privilege CC INT 3 pm=99 Interrupt 3--Protected Mode, more privilege CC INT 3 pm=119 Interrupt 3--from V86 mode to PL 0 CC INT 3 ts Interrupt 3--Protected Mode, via task gate CD ib INT imm8 37 Interrupt numbered by immediate byte CD ib INT imm8 pm=59 Interrupt--Protected Mode, same privilege CD ib INT imm8 pm=99 Interrupt--Protected Mode, more privilege CD ib INT imm8 pm=119 Interrupt--from V86 mode to PL 0 CD ib INT imm8 ts Interrupt--Protected Mode, via task gate CE INTO Fail:3,pm=3; Pass:35 Interrupt 4--if overflow flag is 1 CE INTO pm=59 Interrupt 4--Protected Mode, same privilege CE INTO pm=99 Interrupt 4--Protected Mode, more privilege CE INTO pm=119 Interrupt 4--from V86 mode to PL 0 CE INTO ts Interrupt 4--Protected Mode, via task gate
New Task Old Task 386 TSS 386 TSS 286 TSS VM = 0 VM = 1 386 TSS VM=0 309 226 282 386 TSS VM=1 314 231 287 286 TSS 307 224 280
IF PE = 0 THEN GOTO REAL-ADDRESS-MODE; ELSE GOTO PROTECTED-MODE; FI; REAL-ADDRESS-MODE: Push (FLAGS); IF = 0; (* Clear interrupt flag *) TF = 0; (* Clear trap flag *) Push(CS); Push(IP); (* No error codes are pushed *) CS := IDT[Interrupt number * 4].selector; IP := IDT[Interrupt number * 4].offset; PROTECTED-MODE: Interrupt vector must be within IDT table limits, else #GP(vector number * 8+2+EXT); Descriptor AR byte must indicate interrupt gate, trap gate, or task gate, else #GP(vector number * 8+2+EXT); IF software interrupt (* i.e. caused by INT n, INT 3, or INTO *) THEN IF gate descriptor DPL < CPL THEN #GP(vector number * 8+2+EXT); FI; FI; Gate must be present, else #NP(vector number * 8+2+EXT); IF trap gate OR interrupt gate THEN GOTO TRAP-GATE-OR-INTERRUPT-GATE; ELSE GOTO TASK-GATE; FI; TRAP-GATE-OR-INTERRUPT-GATE: Examine CS selector and descriptor given in the gate descriptor; Selector must be non-null, else #GP (EXT); Selector must be within its descriptor table limits ELSE #GP(selector+EXT); Descriptor AR byte must indicate code segment ELSE #GP(selector + EXT); Segment must be present, else #NP(selector+EXT); IF code segment is non-conforming AND DPL < CPL THEN GOTO INTERRUPT-TO-INNER-PRIVILEGE; ELSE IF code segment is conforming OR code segment DPL = CPL THEN GOTO INTERRUPT-TO-SAME-PRIVILEGE-LEVEL; ELSE #GP(CS selector + EXT); FI; FI; INTERRUPT-TO-INNER-PRIVILEGE: Check selector and descriptor for new stack in current TSS; Selector must be non-null, else #GP(EXT); Selector index must be within its descriptor table limits ELSE #TS(SS selector+EXT); Selector's RPL must equal DPL of code segment, else #TS(SS selector+EXT); Stack segment DPL must equal DPL of code segment, else #TS(SS selector+EXT); Descriptor must indicate writable data segment, else #TS(SS selector+EXT); Segment must be present, else #SS(SS selector+EXT); IF 32-bit gate THEN New stack must have room for 20 bytes else #SS(0) ELSE New stack must have room for 10 bytes else #SS(0) FI; Instruction pointer must be within CS segment boundaries else #GP(0); Load new SS and eSP value from TSS; IF 32-bit gate THEN CS:EIP := selector:offset from gate; ELSE CS:IP := selector:offset from gate; FI; Load CS descriptor into invisible portion of CS register; Load SS descriptor into invisible portion of SS register; IF 32-bit gate THEN Push (long pointer to old stack) (* 3 words padded to 4 *); Push (EFLAGS); Push (long pointer to return location) (* 3 words padded to 4*); ELSE Push (long pointer to old stack) (* 2 words *); Push (FLAGS); Push (long pointer to return location) (* 2 words *); FI; Set CPL to new code segment DPL; Set RPL of CS to CPL; IF interrupt gate THEN IF = 0 (* interrupt flag to 0 (disabled) *); FI; TF := 0; NT := 0; INTERRUPT-FROM-V86-MODE: TempEFlags := EFLAGS; VM := 0; TF := 0; IF service through Interrupt Gate THEN IF = 0; TempSS := SS; TempESP := ESP; SS := TSS.SS0; (* Change to level 0 stack segment *) ESP := TSS.ESP0; (* Change to level 0 stack pointer *) Push(GS); (* padded to two words *) Push(FS); (* padded to two words *) Push(DS); (* padded to two words *) Push(ES); (* padded to two words *) GS := 0; FS := 0; DS := 0; ES := 0; Push(TempSS); (* padded to two words *) Push(TempESP); Push(TempEFlags); Push(CS); (* padded to two words *) Push(EIP); CS:EIP := selector:offset from interrupt gate; (* Starts execution of new routine in 80386 Protected Mode *) INTERRUPT-TO-SAME-PRIVILEGE-LEVEL: IF 32-bit gate THEN Current stack limits must allow pushing 10 bytes, else #SS(0); ELSE Current stack limits must allow pushing 6 bytes, else #SS(0); FI; IF interrupt was caused by exception with error code THEN Stack limits must allow push of two more bytes; ELSE #SS(0); FI; Instruction pointer must be in CS limit, else #GP(0); IF 32-bit gate THEN Push (EFLAGS); Push (long pointer to return location); (* 3 words padded to 4 *) CS:EIP := selector:offset from gate; ELSE (* 16-bit gate *) Push (FLAGS); Push (long pointer to return location); (* 2 words *) CS:IP := selector:offset from gate; FI; Load CS descriptor into invisible portion of CS register; Set the RPL field of CS to CPL; Push (error code); (* if any *) IF interrupt gate THEN IF = 0; FI; TF := 0; NT := 0; TASK-GATE: Examine selector to TSS, given in task gate descriptor; Must specify global in the local/global bit, else #TS(TSS selector); Index must be within GDT limits, else #TS(TSS selector); AR byte must specify available TSS (bottom bits 00001), else #TS(TSS selector; TSS must be present, else #NP(TSS selector); SWITCH-TASKS with nesting to TSS; IF interrupt was caused by fault with error code THEN Stack limits must allow push of two more bytes, else #SS(0); Push error code onto stack; FI; Instruction pointer must be in CS limit, else #GP(0);
The INTO conditional software instruction is identical to the INT interrupt instruction except that the interrupt number is implicitly 4, and the interrupt is made only if the 80386 overflow flag is set.
The first 32 interrupts are reserved by Intel for system use. Some of these interrupts are use for internally generated exceptions.
INT n generally behaves like a far call except that the flags register is pushed onto the stack before the return address. Interrupt procedures return via the IRET instruction, which pops the flags and return address from the stack.
In Real Address Mode, INT n pushes the flags, CS, and the return IP onto the stack, in that order, then jumps to the long pointer indexed by the interrupt number.
up:
Chapter 17 -- 80386 Instruction Set
prev: INS/INSB/INSW/INSD Input from Port to String
next: IRET/IRETD Interrupt Return