Operation
IF instruction = near RET
THEN;
IF OperandSize = 16
THEN
IP Pop();
EIP EIP AND 0000FFFFH;
ELSE (* OperandSize = 32 *)
EIP Pop();
FI;
IF instruction has immediate operand THEN eSP eSP + imm16; FI;
FI;
IF (PE = 0 OR (PE = 1 AND VM = 1))
(* real mode or virtual 8086 mode *)
AND instruction = far RET
THEN;
IF OperandSize = 16
THEN
IP Pop();
EIP EIP AND 0000FFFFH;
CS Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 32 *)
EIP Pop ();
CS Pop(); (* 32-bit pop, high-order 16-bits discarded *)
FI;
IF instruction has immediate operand THEN eSP eSP + imm16; FI;
FI;
IF (PE = 1 AND VM = 0) (* Protected mode, not V86 mode *)
AND instruction = far RET
THEN
IF OperandSize=32
THEN Third word on stack must be within stack limits else #SS(0);
ELSE Second word on stack must be within stack limits else #SS(0);
FI;
Return selector RPL must be ≤ CPL ELSE #GP(return selector)
IF return selector RPL = CPL
THEN GOTO SAME-LEVEL;
ELSE GOTO OUTER-PRIVILEGE-LEVEL;
FI;
FI;
SAME-LEVEL:
Return selector must be non-null ELSE #GP(0)
Selector index must be within its descriptor table limits ELSE
#GP(selector)
Descriptor AR byte must indicate code segment ELSE #GP(selector)
IF non-conforming
THEN code segment DPL must equal CPL;
ELSE #GP(selector);
FI;
IF conforming
THEN code segment DPL must be ≤ CPL;
ELSE #GP(selector);
FI;
Code segment must be present ELSE #NP(selector);
Top word on stack must be within stack limits ELSE #SS(0);
IP must be in code segment limit ELSE #GP(0);
IF OperandSize=32
THEN
Load CS:EIP from stack
Load CS register with descriptor
Increment eSP by 8 plus the immediate offset if it exists
ELSE (* OperandSize=16 *)
Load CS:IP from stack
Load CS register with descriptor
Increment eSP by 4 plus the immediate offset if it exists
FI;
OUTER-PRIVILEGE-LEVEL:
IF OperandSize=32
THEN Top (16+immediate) bytes on stack must be within stack limits
ELSE #SS(0);
ELSE Top (8+immmediate) bytes on stack must be within stack limits ELSE
#SS(0);
FI;
Examine return CS selector and associated descriptor:
Selector must be non-null ELSE #GP(0);
Selector index must be within its descriptor table limits ELSE
#GP(selector)
Descriptor AR byte must indicate code segment ELSE #GP(selector);
IF non-conforming
THEN code segment DPL must equal return selector RPL
ELSE #GP(selector);
FI;
IF conforming
THEN code segment DPL must be ≤ return selector RPL;
ELSE #GP(selector);
FI;
Segment must be present ELSE #NP(selector)
Examine return SS selector and associated descriptor:
Selector must be non-null ELSE #GP(0);
Selector index must be within its descriptor table limits
ELSE #GP(selector);
Selector RPL must equal the RPL of the return CS selector ELSE
#GP(selector);
Descriptor AR byte must indicate a writable data segment ELSE
#GP(selector);
Descriptor DPL must equal the RPL of the return CS selector ELSE
#GP(selector);
Segment must be present ELSE #NP(selector);
IP must be in code segment limit ELSE #GP(0);
Set CPL to the RPL of the return CS selector;
IF OperandSize=32
THEN
Load CS:EIP from stack;
Set CS RPL to CPL;
Increment eSP by 8 plus the immediate offset if it exists;
Load SS:eSP from stack;
ELSE (* OperandSize=16 *)
Load CS:IP from stack;
Set CS RPL to CPL;
Increment eSP by 4 plus the immediate offset if it exists;
Load SS:eSP from stack;
FI;
Load the CS register with the return CS descriptor;
Load the SS register with the return SS descriptor;
For each of ES, FS, GS, and DS
DO
IF the current register setting is not valid for the outer level,
set the register to null (selector AR 0);
To be valid, the register setting must satisfy the following properties:
Selector index must be within descriptor table limits;
Descriptor AR byte must indicate data or readable code segment;
IF segment is data or non-conforming code, THEN
DPL must be ≥ CPL, or DPL must be ≥ RPL;
FI;
OD;
[Back: Description]
[Next: Protected Mode Exceptions]