<<<    Index    >>>
3-57
INSTRUCTION SET REFERENCE
CALL—Call Procedure (Continued)
Push(CS); (* padded with 16 high-order bits *)
Push(EIP);
CS 
<
 DEST[47:32]; (* DEST is ptr16:32 or [m16:32] *)
EIP 
<
 DEST[31:0]; (* DEST is ptr16:32 or [m16:32] *)
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[31:16]; (* DEST is ptr16:16 or [m16:16] *)
EIP 
<
 DEST[15:0]; (* DEST is ptr16:16 or [m16:16] *)
EIP 
<
 EIP AND 0000FFFFH; (* clear upper 16 bits *)
FI;
FI;
IF far call AND (PE = 1 AND VM = 0) (* Protected mode, not virtual-8086 mode *)
THEN
IF segment selector in target operand null THEN #GP(0); FI;
IF segment selector index not within descriptor table limits
THEN #GP(new code segment selector);
FI;
Read type and access rights of selected segment descriptor;
IF segment type is not a conforming or nonconforming code segment, call gate,
task gate, or TSS THEN #GP(segment selector); FI;
Depending on type and access rights
GO TO CONFORMING-CODE-SEGMENT;
GO TO NONCONFORMING-CODE-SEGMENT;
GO TO CALL-GATE;
GO TO TASK-GATE;
GO TO TASK-STATE-SEGMENT;
FI;
CONFORMING-CODE-SEGMENT:
IF DPL > CPL THEN #GP(new code segment selector); FI;
IF segment not present THEN #NP(new code segment selector); FI;
IF OperandSize = 32
THEN
IF stack not large enough for a 6-byte return address THEN #SS(0); FI;
IF the instruction pointer is not within code segment limit THEN #GP(0); FI;
Push(CS); (* padded with 16 high-order bits *)
Push(EIP);
CS 
<
 DEST(NewCodeSegmentSelector); 
(* segment descriptor information also loaded *)
CS(RPL) 
<
 CPL
EIP 
<
 DEST(offset);
<<<    Index    >>>