background image

5-22 Vol. 3A

PROTECTION

Stack pointer — Update RSP using 64-bit canonical address in RCX.

When SYSEXIT transfers control to compatibility mode user code when the operand size attribute is 32 bits, the 
following fields are generated and bits set:

Target code segment — Computed by adding 16 to the value in IA32_SYSENTER_CS.

New CS attributes — L-bit = 0 (go to compatibility mode).

Target instruction — Fetch the target instruction from 32-bit address in EDX.

Stack segment — Computed by adding 24 to the value in IA32_SYSENTER_CS.

Stack pointer — Update ESP from 32-bit address in ECX.

5.8.8 

Fast System Calls in 64-Bit Mode

The SYSCALL and SYSRET instructions are designed for operating systems that use a flat memory model (segmen-
tation is not used). The instructions, along with SYSENTER and SYSEXIT, are suited for IA-32e mode operation. 
SYSCALL and SYSRET, however, are not supported in compatibility mode (or in protected mode). Use CPUID to 
check if SYSCALL and SYSRET are available (CPUID.80000001H.EDX[bit 11] = 1). 
SYSCALL is intended for use by user code running at privilege level 3 to access operating system or executive 
procedures running at privilege level 0. SYSRET is intended for use by privilege level 0 operating system or execu-
tive procedures for fast returns to privilege level 3 user code. 
Stack pointers for SYSCALL/SYSRET are not specified through model specific registers. The clearing of bits in 
RFLAGS is programmable rather than fixed. SYSCALL/SYSRET save and restore the RFLAGS register. 
For SYSCALL, the processor saves RFLAGS into R11 and the RIP of the next instruction into RCX; it then gets the 
privilege-level 0 target code segment, instruction pointer, stack segment, and flags as follows:

Target code segment — Reads a non-NULL selector from IA32_STAR[47:32].

Target instruction pointer — Reads a 64-bit address from IA32_LSTAR. (The WRMSR instruction ensures 
that the value of the IA32_LSTAR MSR is canonical.)

Stack segment — Computed by adding 8 to the value in IA32_STAR[47:32].

Flags — The processor sets RFLAGS to the logical-AND of its current value with the complement of the value in 
the IA32_FMASK MSR.

When SYSRET transfers control to 64-bit mode user code using REX.W, the processor gets the privilege level 3 
target code segment, instruction pointer, stack segment, and flags as follows:

Target code segment — Reads a non-NULL selector from IA32_STAR[63:48] + 16.

Target instruction pointer — Copies the value in RCX into RIP.

Stack segment — IA32_STAR[63:48] + 8.

EFLAGS — Loaded from R11.

When SYSRET transfers control to 32-bit mode user code using a 32-bit operand size, the processor gets the priv-
ilege level 3 target code segment, instruction pointer, stack segment, and flags as follows:

Target code segment — Reads a non-NULL selector from IA32_STAR[63:48].

Target instruction pointer — Copies the value in ECX into EIP.

Stack segment — IA32_STAR[63:48] + 8.

EFLAGS — Loaded from R11.

It is the responsibility of the OS to ensure the descriptors in the GDT/LDT correspond to the selectors loaded by 
SYSCALL/SYSRET (consistent with the base, limit, and attribute values forced by the instructions). 
See Figure 5-14 for the layout of IA32_STAR, IA32_LSTAR and IA32_FMASK.