Intel 64 and IA-32 Architectures Software Developers Manual Volume 2A, Instruction Set Reference, A-M
3-98 Vol. 2
INSTRUCTION SET REFERENCE, A-M
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);
(* Segment descriptor information also loaded *)
Push(oldSS:oldESP); (* From calling procedure *)
Push(oldCS:oldEIP); (* Return address to calling procedure *)
FI;