3-58
INSTRUCTION SET REFERENCE
CALLCall Procedure (Continued)
ELSE (* OperandSize = 16 *)
IF stack not large enough for a 4-byte return address THEN #SS(0); FI;
IF the instruction pointer is not within code segment limit THEN #GP(0); FI;
Push(CS);
Push(IP);
CS
<
DEST(NewCodeSegmentSelector);
(* segment descriptor information also loaded *)
CS(RPL)
<
CPL
EIP
<
DEST(offset) AND 0000FFFFH; (* clear upper 16 bits *)
FI;
END;
NONCONFORMING-CODE-SEGMENT:
IF (RPL > CPL) OR (DPL
?
CPL) THEN #GP(new code segment selector); FI;
IF segment not present THEN #NP(new code segment selector); FI;
IF stack not large enough for return address THEN #SS(0); FI;
tempEIP
<
DEST(offset)
IF OperandSize=16
THEN
tempEIP
<
tempEIP AND 0000FFFFH; (* clear upper 16 bits *)
FI;
IF tempEIP outside code segment limit THEN #GP(0); FI;
IF OperandSize = 32
THEN
Push(CS); (* padded with 16 high-order bits *)
Push(EIP);
CS
<
DEST(NewCodeSegmentSelector);
(* segment descriptor information also loaded *)
CS(RPL)
<
CPL;
EIP
<
tempEIP;
ELSE (* OperandSize = 16 *)
Push(CS);
Push(IP);
CS
<
DEST(NewCodeSegmentSelector);
(* segment descriptor information also loaded *)
CS(RPL)
<
CPL;
EIP
<
tempEIP;
FI;
END;
CALL-GATE:
IF call gate DPL < CPL or RPL THEN #GP(call gate selector); FI;
IF call gate not present THEN #NP(call gate selector); FI;
IF call gate code-segment selector is null THEN #GP(0); FI;