background image

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.