CALL—Call Procedure (Continued)
FI;
IF stack segment selector is null THEN #TS(stack segment selector); FI;
IF stack segment selector index is not within its descriptor table limits
THEN #TS(SS selector); FI
Read code segment descriptor;
IF stack segment selector's RPL DPL of code segment
OR stack segment DPL DPL of code segment
OR stack segment is not a writable data segment
IF stack segment not present THEN #SS(SS selector); FI;
IF CallGateSize = 32
THEN
ELSE (* CallGateSize = 16 *)
FI;
CPL CodeSegment(DPL)
CS(RPL) CPL
END;
SAME-PRIVILEGE:
IF CallGateSize = 32
THEN
Volume 4: Base IA-32 Instruction Reference
TSSstackAddress new code segment (DPL 4) + 2
IF (TSSstackAddress + 4) TSS limit
THEN #TS(current TSS selector); FI;
newESP TSSstackAddress;
newSS TSSstackAddress + 2;
THEN #TS(SS selector); FI
IF stack does not have room for parameters plus 16 bytes
THEN #SS(SS selector); FI;
IF CallGate(InstructionPointer) not within code segment limit THEN #GP(0); FI;
SS newSS;
(* segment descriptor information also loaded *)
ESP newESP;
CS:EIP CallGate(CS:InstructionPointer);
(* segment descriptor information also loaded *)
Push(oldSS:oldESP); (* from calling procedure *)
temp parameter count from call gate, masked to 5 bits;
Push(parameters from calling procedure's stack, temp)
Push(oldCS:oldEIP); (* return address to calling procedure *)
IF stack does not have room for parameters plus 8 bytes
THEN #SS(SS selector); FI;
IF (CallGate(InstructionPointer) AND FFFFH) not within code segment limit
THEN #GP(0); FI;
SS newSS;
(* segment descriptor information also loaded *)
ESP newESP;
CS:IP CallGate(CS:InstructionPointer);
(* segment descriptor information also loaded *)
Push(oldSS:oldESP); (* from calling procedure *)
temp parameter count from call gate, masked to 5 bits;
Push(parameters from calling procedure's stack, temp)
Push(oldCS:oldEIP); (* return address to calling procedure *)
IF stack does not have room for 8 bytes
THEN #SS(0); FI;
4:53