Operation

Note: The following operational description applies not only to the above instructions but also to external interrupts and exceptions. IF PE = 0
THEN CALL REAL-ADDRESS-MODE;
ELSE
CALL PROTECTED-MODE;
IF task gate
THEN CALL TASK-GATE;
ELSE
CALL TRAP-OR-INT-GATE; (* PE=1, int/trap gate *)
IF code segment is non-conforming AND DPL < CPL
THEN
IF VM=0
THEN CALL INT-TO-INNER-PRIV; (*PE=1,int/trap gate,DPL<CPL,VM=0*)
ELSE CALL INT-FROM-V86-MODE; (* PE=1, int/trap gate, DPL<CPL,
VM=1 *)
FI;
ELSE (* PE=1, int/trap gate, DPL ≥ CPL *)
IF code segment is conforming OR code segment DPL = CPL
THEN CALL INT-TO-SAME-PRIV;
ELSE #GP(CS selector + EXT); (* PE=1, int/trap gate, DPL>CPL *)
FI;
FI;
FI;
FI;
END;

REAL-ADDRESS-MODE PROC
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;
(* Start processing in real address mode *)
REAL-ADDRESS-MODE ENDPROC

PROTECTED-MODE PROC
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); (* PE=1, DPL<CPL, software interrupt *)
FI;
FI;
Gate must be present, else #NP(vector number * 8+2+EXT);
PROTECTED-MODE ENDPROC

TRAP-OR-INT-GATE PROC
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);
TRAP-OR-INT-GATE ENDPROC

INT-TO-INNER-PRIV PROC
(* PE=1, DPL<CPL and non-conforming, (* PE=1, int/trap gate, DPL<CPL, VM=0 *)
Check selector and descriptor for new stack in current TSS;
Selector must be non-null, else #TS(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 (disable) *); FI;
TF  0;
NT  0;
INT-FROM-INNER-PRIV ENDPROC

INT-FROM-V86-MODE PROC
Check selector and descriptor for new stack in current TSS;
Selector must be non-null, else #TS(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);
IF IOPL < 3
THEN
#GP(0); (*V86 monitor trap: PE=1,int/trap gate, DPL<CPL, VM=1, IOPL<3*)
ELSE (* IOPL=3 *)
IF GATE'S_DPL = 3
THEN
IF TARGET'S_CPL <> 0
THEN #GP(0);
ELSE
TempEFlags  EFLAGS;
VM  0;
TF  0;
IF service through Interrupt Gate
THEN IF  0;
FI;
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; (* segment registers nullified - invalid in
protected mode *)
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 processing of new routine in Protected Mode *)
FI;
ELSE (* GATE'S_DPL <> 3 *)
#GP(0);
FI;
FI;
INT-FROM-V86-MODE ENDPROC

INT-TO-SAME-PRIV PROC
(* PE=1, DPL=CPL or conforming segment *)
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 to 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;
INT-TO-SAME-PRIV ENDPROC

TASK-GATE PROC (* PE=1, 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);
TASK-GATE ENDPROC


[Back: Description]
[Next: Decision Table]