Vol. 2A 3-99
INSTRUCTION SET REFERENCE, A-M
CALL—Call Procedure
or stack segment DPL ≠ DPL of code segment or stack segment is not a
writable data segment)
THEN #TS(SS selector); FI
IF IA32_EFER.LMA = 0 and stack segment not present
THEN #SS(SS selector); FI;
IF CallGateSize
= 32
THEN
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 *)
ELSE
IF CallGateSize = 16
THEN
IF stack does not have room for parameters plus 8 bytes
THEN #SS(SS selector); FI;
IF (CallGate(InstructionPointer) AND FFFFH) not in 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 *)
ELSE (* CallGateSize = 64 *)
IF pushing 32 bytes on the stack touches non-canonical addresses
THEN #SS(SS selector); FI;
IF (CallGate(InstructionPointer) is non-canonical)
THEN #GP(0); FI;
SS ← newSS; (* New SS is NULL)
RSP ← newESP;
CS:IP ← CallGate(CS:InstructionPointer);