5-20 Vol. 3A
PROTECTION
5.8.6
Returning from a Called Procedure
The RET instruction can be used to perform a near return, a far return at the same privilege level, and a far return
to a different privilege level. This instruction is intended to execute returns from procedures that were called with
a CALL instruction. It does not support returns from a JMP instruction, because the JMP instruction does not save a
return instruction pointer on the stack.
A near return only transfers program control within the current code segment; therefore, the processor performs
only a limit check. When the processor pops the return instruction pointer from the stack into the EIP register, it
checks that the pointer does not exceed the limit of the current code segment.
On a far return at the same privilege level, the processor pops both a segment selector for the code segment being
returned to and a return instruction pointer from the stack. Under normal conditions, these pointers should be
valid, because they were pushed on the stack by the CALL instruction. However, the processor performs privilege
checks to detect situations where the current procedure might have altered the pointer or failed to maintain the
stack properly.
A far return that requires a privilege-level change is only allowed when returning to a less privileged level (that is,
the DPL of the return code segment is numerically greater than the CPL). The processor uses the RPL field from the
CS register value saved for the calling procedure (see Figure 5-13) to determine if a return to a numerically higher
privilege level is required. If the RPL is numerically greater (less privileged) than the CPL, a return across privilege
levels occurs.
The processor performs the following steps when performing a far return to a calling procedure (see Figures 6-2
and 6-4 in the IntelĀ® 64 and IA-32 Architectures Software Developerās Manual, Volume 1, for an illustration of the
stack contents prior to and after a return):
1. Checks the RPL field of the saved CS register value to determine if a privilege level change is required on the
return.
2. Loads the CS and EIP registers with the values on the called procedureās stack. (Type and privilege level checks
are performed on the code-segment descriptor and RPL of the code- segment selector.)
3. (If the RET instruction includes a parameter count operand and the return requires a privilege level change.)
Adds the parameter count (in bytes obtained from the RET instruction) to the current ESP register value (after
popping the CS and EIP values), to step past the parameters on the called procedureās stack. The resulting
value in the ESP register points to the saved SS and ESP values for the calling procedureās stack. (Note that the
byte count in the RET instruction must be chosen to match the parameter count in the call gate that the calling
procedure referenced when it made the original call multiplied by the size of the parameters.)
4. (If the return requires a privilege level change.) Loads the SS and ESP registers with the saved SS and ESP
values and switches back to the calling procedureās stack. The SS and ESP values for the called procedureās
stack are discarded. Any limit violations detected while loading the stack-segment selector or stack pointer
cause a general-protection exception (#GP) to be generated. The new stack-segment descriptor is also
checked for type and privilege violations.
5. (If the RET instruction includes a parameter count operand.) Adds the parameter count (in bytes obtained from
the RET instruction) to the current ESP register value, to step past the parameters on the calling procedureās
stack. The resulting ESP value is not checked against the limit of the stack segment. If the ESP value is beyond
the limit, that fact is not recognized until the next stack operation.
6. (If the return requires a privilege level change.) Checks the contents of the DS, ES, FS, and GS segment
registers. If any of these registers refer to segments whose DPL is less than the new CPL (excluding conforming
code segments), the segment register is loaded with a null segment selector.
See the description of the RET instruction in Chapter 4 of the IntelĀ® 64 and IA-32 Architectures Software Devel-
operās Manual, Volume 2B, for a detailed description of the privilege level checks and other protection checks that
the processor performs on a far return.
5.8.7
Performing Fast Calls to System Procedures with the
SYSENTER and SYSEXIT Instructions
The SYSENTER and SYSEXIT instructions were introduced into the IA-32 architecture in the Pentium II processors
for the purpose of providing a fast (low overhead) mechanism for calling operating system or executive procedures.