CALL—Call Procedure (Continued)
IF stack not large enough for return address THEN #SS(0); FI;
tempEIP DEST(offset)
IF OperandSize=16
THEN
FI;
IF tempEIP outside code segment limit THEN #GP(0); FI;
IF OperandSize = 32
THEN
ELSE (* OperandSize = 16 *)
FI;
IF Itanium System Environment AND PSR.tb THEN IA_32_Exception(Debug);
END;
CALL-GATE:
IF call gate DPL < CPL or RPL THEN #GP(call gate selector); FI;
IF not present THEN #NP(call gate selector); FI;
IF Itanium System Environment THEN IA-32_Intercept(Gate,CALL);
IF call gate code-segment selector is null THEN #GP(0); FI;
IF call gate code-segment selector index is outside descriptor table limits
THEN #GP(code segment selector); FI;
Read code segment descriptor;
IF code-segment segment descriptor does not indicate a code segment
OR code-segment segment descriptor DPL > CPL
THEN #GP(code segment selector); FI;
IF code segment not present THEN #NP(new code segment selector); FI;
IF code segment is non-conforming AND DPL < CPL
THEN go to MORE-PRIVILEGE;
ELSE go to SAME-PRIVILEGE;
FI;
END;
MORE-PRIVILEGE:
IF current TSS is 32-bit TSS
THEN
ELSE (* TSS is 16-bit *)
4:52
tempEIP tempEIP AND 0000FFFFH; (* clear upper 16 bits *)
Push(CS); (* padded with 16 high-order bits *)
Push(EIP);
CS DEST(NewCodeSegmentSelector);
(* segment descriptor information also loaded *)
CS(RPL) CPL;
EIP tempEIP;
Push(CS);
Push(IP);
CS DEST(NewCodeSegmentSelector);
(* segment descriptor information also loaded *)
CS(RPL) CPL;
EIP tempEIP;
TSSstackAddress new code segment (DPL 8) + 4
IF (TSSstackAddress + 7) TSS limit
THEN #TS(current TSS selector); FI;
newSS TSSstackAddress + 4;
newESP stack address;
Volume 4: Base IA-32 Instruction Reference