<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="../style/style.css" />
<title>IRET/IRETD: Interrupt Return (x86 Instruction Set Reference)</title>
</head>
<body>
<div class="main_container"><h1>x86 Instruction Set Reference</h1>
<title>IRET/IRETD: Interrupt Return (x86 Instruction Set Reference)</title>
<h1>IRET/IRETD</h1>
<h2>Interrupt Return</h2>
<object>
<table class="box">
<tr>
<th>Opcode</th>
<th>Mnemonic</th>
<th>Description</th>
</tr>
<tr>
<td class="grid"><code>CF</code></td>
<td class="grid"><code>IRET</code></td>
<td class="grid">Interrupt return (16-bit operand size).</td>
</tr>
<tr>
<td class="grid"><code>CF</code></td>
<td class="grid"><code>IRETD</code></td>
<td class="grid">Interrupt return (32-bit operand size).</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Description</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<p>Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or when an interrupt or exception causes a task switch to an interrupt or exception handler.) See the section titled "Task Linking" in Chapter 6 of the IA-32 Intel Architecture Software Developer's Manual, Volume 3.</p>
<p>IRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the IRET mnemonic interchangeably for both operand sizes.</p>
<p>In Real-Address Mode, the IRET instruction preforms a far return to the interrupted program or procedure. During this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure.</p>
<p>In Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting of these flags, the processor performs the following types of interrupt returns:</p>
<ul>
<li>Return from virtual-8086 mode.</li>
<li>Return to virtual-8086 mode.</li>
<li>Intra-privilege level return.</li>
<li>Inter-privilege level return.</li>
<li>Return from nested task (task switch).</li>
</ul>
<p>If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch. The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack). As with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the data segment registers from the stack.</p>
<p>If the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a CALL instruction, an interrupt, or an exception) back to the calling or inter- rupted task. The updated state of the task executing the IRET instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET instruction is executed.</p>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Operation</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<pre><span class="keyword">if</span><span class="operator">(</span>PE <span class="operator">==</span> <span class="number">0</span><span class="operator">)</span> {
<span class="comment">//Real-Address-Mode</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">12</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 12 bytes of stack not within stack limits</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimits<span class="operator">(</span>InstructionPointer<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
CS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//32-bit pop, high-order 16 bits discarded</span>
TemporaryEFLAGS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
EFLAGS <span class="operator">=</span> <span class="operator">(</span>TemporaryEFLAGS <span class="operator">&</span> <span class="number">0x257FD5</span><span class="operator">)</span> <span class="operator">|</span> <span class="operator">(</span>EFLAGS <span class="operator">&</span> <span class="number">0x1A0000</span><span class="operator">)</span><span class="operator">;</span>
}
<span class="keyword">else</span> { <span class="comment">//OperandSize is 16</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">6</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 6 bytes of stack not within stack limits</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimits<span class="operator">(</span>InstructionPointer<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> EIP <span class="operator">&</span> <span class="number">0xFFFF</span><span class="operator">;</span>
CS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//16-bit pop</span>
EFLAGS<span class="operator">[</span><span class="number">0..15</span><span class="operator">]</span> <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
}
<span class="comment">//END</span>
}
<span class="keyword">else</span> {
<span class="comment">//Protected Mode</span>
<span class="keyword">if</span><span class="operator">(</span>VM <span class="operator">==</span> <span class="number">1</span><span class="operator">)</span> {
<span class="comment">//Virtual-8086 mode: PE == 1, VM == 1</span>
<span class="comment">//Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode</span>
<span class="keyword">if</span><span class="operator">(</span>IOPL <span class="operator">==</span> <span class="number">3</span><span class="operator">)</span> { <span class="comment">//Virtual mode: PE=1, VM=1, IOPL=3</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">12</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 12 bytes of stack not within stack limits</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimits<span class="operator">(</span>InstructionPointer<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
CS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//32-bit pop, high-order 16 bits discarded</span>
EFLAGS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
<span class="comment">//VM, IOPL, VIP and VIF EFLAGS bits are not modified by pop</span>
}
<span class="keyword">else</span> { <span class="comment">//OperandSize is 16</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">6</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 6 bytes of stack not within stack limits</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimits<span class="operator">(</span>InstructionPointer<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> EIP <span class="operator">&</span> <span class="number">0xFFFF</span><span class="operator">;</span>
CS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//16-bit pop</span>
EFLAGS<span class="operator">[</span><span class="number">0..15</span><span class="operator">]</span> <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
<span class="comment">//VM, IOPL, VIP and VIF EFLAGS bits are not modified by pop</span>
}
}
<span class="keyword">else</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//trap to virtual-8086 monitor: PE == 1, VM == 1, IOPL < 3</span>
<span class="comment">//END</span>
}
<span class="keyword">if</span><span class="operator">(</span>NT <span class="operator">==</span> <span class="number">1</span><span class="operator">)</span> {
<span class="comment">//Task return</span>
<span class="comment">//PE == 1, VM == 0, NT == 1</span>
SegmentSelector <span class="operator">=</span> ReadSegmentSelector<span class="operator">(</span>CurrentTSS<span class="operator">.</span>LinkField<span class="operator">)</span><span class="operator">;</span> <span class="comment">//Read segment selector in link field of current TSS</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsGlobal<span class="operator">(</span><span class="operator">)</span> <span class="comment">/*local/global bit is set to local*/</span> <span class="operator">||</span> <span class="operator">!</span>IsWithinGDTLimits<span class="operator">(</span>Index<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>TS<span class="operator">(</span>TSSSelector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
TSSDescriptor <span class="operator">=</span> AccessTSS<span class="operator">(</span>CurrentTSS<span class="operator">.</span>LinkField<span class="operator">.</span>Task<span class="operator">)</span><span class="operator">;</span> <span class="comment">//Access TSS for task specified in link field of current TSS</span>
<span class="keyword">if</span><span class="operator">(</span>TSSDescriptor<span class="operator">.</span>Type <span class="operator">!=</span> TSS <span class="operator">||</span> <span class="operator">!</span>IsBusy<span class="operator">(</span>TSS<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>TS<span class="operator">(</span>TSSSelector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsPresent<span class="operator">(</span>TSS<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>NP<span class="operator">(</span>TSSSelector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
SwitchTasks<span class="operator">(</span>CurrenTSS<span class="operator">.</span>LinkField<span class="operator">.</span>TSS<span class="operator">,</span> WithoutNesting<span class="operator">)</span><span class="operator">;</span> <span class="comment">//Switch tasks (without nesting) to TSS specified in link field of current TSS</span>
SetBusyState<span class="operator">(</span>AbandonedTask<span class="operator">,</span> NotBusy<span class="operator">)</span><span class="operator">;</span> <span class="comment">//Mark the task just abandoned as NOT BUSY</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimit<span class="operator">(</span>EIP<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="comment">//END</span>
}
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">12</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 12 bytes of stack not within stack limits</span>
TemporaryEIP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
TemporaryCS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
TemporaryEFLAGS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
}
<span class="keyword">else</span> { <span class="comment">//OperandSize == 16</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">6</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 6 bytes of stack not within stack limits</span>
TemporaryEIP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
TemporaryCS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
TemporaryEFLAGS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
TemporaryEIP <span class="operator">=</span> TemporaryEIP <span class="operator">&</span> <span class="number">0xFFFF</span><span class="operator">;</span>
TemporaryEFLAGS <span class="operator">=</span> TemporaryEFLAGS <span class="operator">&</span> <span class="number">0xFFFF</span><span class="operator">;</span>
}
<span class="keyword">if</span><span class="operator">(</span>TemporaryEFLAGS<span class="operator">.</span>VM <span class="operator">==</span> <span class="number">1</span> <span class="operator">&&</span> CPL <span class="operator">==</span> <span class="number">0</span><span class="operator">)</span> {
<span class="comment">//Interrupted procedure was in virtual-8086 mode: PE == 1, VM == 1 in flags image</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">24</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 24 bytes of stack not within stack limits</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimits<span class="operator">(</span>InstructionPointer<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
CS <span class="operator">=</span> TemporaryCS<span class="operator">;</span>
EIP <span class="operator">=</span> TemporaryEIP<span class="operator">;</span>
EFLAGS <span class="operator">=</span> TemporaryEFLAGS<span class="operator">;</span>
TemporaryESP <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
TemporarySS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
ES <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//pop 2 words; throw away high-order word</span>
DS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//pop 2 words; throw away high-order word</span>
FS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//pop 2 words; throw away high-order word</span>
GS <span class="operator">=</span> Pop<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//pop 2 words; throw away high-order word</span>
SS<span class="operator">:</span>ESP <span class="operator">=</span> TemporarySS<span class="operator">:</span>TemporaryESP<span class="operator">;</span>
CPL <span class="operator">=</span> <span class="number">3</span><span class="operator">;</span>
ResumeExecution<span class="operator">(</span><span class="operator">)</span> <span class="comment">//Resume execution in Virtual-8086 mode</span>
}
<span class="keyword">else</span> {
<span class="comment">//Protected mode return</span>
<span class="comment">//PE == 1, VM == 0 in flags image</span>
<span class="keyword">if</span><span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentSelector <span class="operator">==</span> <span class="number">0</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinDescriptorTableLimits<span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>AddressesDescriptor<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span>Selector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
ReturnCode<span class="operator">.</span>SegmentDescriptor <span class="operator">=</span> ReadSegmentDescriptor<span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsCodeSegment<span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentDescriptor<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span>Selector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>RPL <span class="operator"><</span> CPL<span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span>Selector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>IsConforming<span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentDescriptor<span class="operator">)</span> <span class="operator">&&</span> ReturnCode<span class="operator">.</span>Segment<span class="operator">.</span>DPL <span class="operator">></span> ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>RPL<span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span>Selector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>RPL <span class="operator">></span> CPL<span class="operator">)</span> {
<span class="comment">//Return to outer privilege level</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span> <span class="operator">&&</span> <span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">8</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 8 bytes of stack not within stack limits</span>
<span class="keyword">else</span> <span class="comment">/*OperandSize == 16*/</span> <span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinStackLimits<span class="operator">(</span>TopStackBytes<span class="operator">(</span><span class="number">4</span><span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span> <span class="comment">//top 4 bytes of stack not within stack limits</span>
StackSegmentSelector <span class="operator">=</span> ReadReturnSegmentSelector<span class="operator">(</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>StackSegmentSelector <span class="operator">==</span> <span class="number">0</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinDescriptorTableLimits<span class="operator">(</span>ReturnStackSegmentSelector<span class="operator">.</span>Index<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span>SSSelector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
SegmentDescriptor <span class="operator">=</span> ReadSegmenDescriptor<span class="operator">(</span>ReturnSegmentSelector<span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>StackSegmentSelector<span class="operator">.</span>RPL <span class="operator">!=</span> ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>RPL<span class="operator">)</span> {
<span class="keyword">if</span><span class="operator">(</span>StackSegmentSelector<span class="operator">.</span>RPL <span class="operator">!=</span> ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>RPL <span class="operator">||</span> <span class="operator">!</span>IndicatesWritableDataSegment<span class="operator">(</span>StackSegmentDescriptor<span class="operator">)</span> <span class="operator">||</span> StackSegment<span class="operator">.</span>DPL <span class="operator">!=</span> ReturnCode<span class="operator">.</span>SegmentSelector<span class="operator">.</span>RPL<span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span>SSSelector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsPresent<span class="operator">(</span>StackSegment<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>SS<span class="operator">(</span>SSSelector<span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
}
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimit<span class="operator">(</span>TemporaryEIP<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> TemporaryIP<span class="operator">;</span>
CS <span class="operator">=</span> TemporaryCS<span class="operator">;</span>
EFLAGS<span class="operator">.</span>CF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>CF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>PF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>PF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>AF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>ZF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>SF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>SF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>TF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>DF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>OF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>OF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>NT <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>NT<span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
EFLAGS<span class="operator">.</span>RF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>RF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>AC <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>AC<span class="operator">;</span>
EFLAGS<span class="operator">.</span>ID <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>ID<span class="operator">;</span>
}
<span class="keyword">if</span><span class="operator">(</span>CPL <span class="operator"><=</span> IOPL<span class="operator">)</span> EFLAGS<span class="operator">.</span>IF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>IF<span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>CPL <span class="operator">==</span> <span class="number">0</span><span class="operator">)</span> {
EFLAGS<span class="operator">.</span>IOPL <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>IOPL<span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
EFLAGS<span class="operator">.</span>VM <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>VM<span class="operator">;</span>
EFLAGS<span class="operator">.</span>VIF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>VIF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>VIP <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>VIP<span class="operator">;</span>
}
}
<span class="comment">//perform operation for each of the segment registers</span>
SegmentRegisters<span class="operator">[</span><span class="operator">]</span> <span class="operator">=</span> {ES<span class="operator">,</span> FS<span class="operator">,</span> GS<span class="operator">,</span> DS}<span class="operator">;</span>
<span class="keyword">while</span><span class="operator">(</span>SegmentRegister <span class="operator">=</span> SegmentRegisters<span class="operator">.</span>Next<span class="operator">(</span><span class="operator">)</span><span class="operator">)</span> <span class="keyword">if</span><span class="operator">(</span><span class="operator">(</span>PointsToDate<span class="operator">(</span>SegmentRegister<span class="operator">)</span> <span class="operator">||</span> <span class="operator">!</span>IsConformingCodeSegment<span class="operator">(</span>SegmentRegister<span class="operator">)</span><span class="operator">)</span> <span class="operator">&&</span> CPL <span class="operator">></span> SegmentDescriptor<span class="operator">.</span>DPL <span class="comment">/*stored in hidden part of segment register*/</span><span class="operator">)</span> SegmentSelector <span class="operator">=</span> <span class="number">0</span><span class="operator">;</span> <span class="comment">//segment register invalid; null segment selector</span>
<span class="comment">//END</span>
}
<span class="keyword">else</span> {
<span class="comment">//Same privilege level</span>
<span class="comment">//PE=1, VM=0 in flags image, RPL=CPL</span>
<span class="keyword">if</span><span class="operator">(</span><span class="operator">!</span>IsWithinCodeSegmentLimits<span class="operator">(</span>EIP<span class="operator">)</span><span class="operator">)</span> Exception<span class="operator">(</span>GP<span class="operator">(</span><span class="number">0</span><span class="operator">)</span><span class="operator">)</span><span class="operator">;</span>
EIP <span class="operator">=</span> TemporaryEIP<span class="operator">;</span>
CS <span class="operator">=</span> TemporaryCS<span class="operator">;</span> <span class="comment">//segment descriptor information also loaded</span>
EFLAGS<span class="operator">.</span>CF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>CF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>PF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>PF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>AF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>ZF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>SF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>SF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>TF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>DF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>OF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>OF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>NT <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>NT<span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
EFLAGS<span class="operator">.</span>RF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>RF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>AC <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>AC<span class="operator">;</span>
EFLAGS<span class="operator">.</span>ID <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>ID<span class="operator">;</span>
}
<span class="keyword">if</span><span class="operator">(</span>CPL <span class="operator"><=</span> IOPL<span class="operator">)</span> EFLAGS<span class="operator">.</span>IF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>IF<span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>CPL <span class="operator">==</span> <span class="number">0</span><span class="operator">)</span> {
EFLAGS<span class="operator">.</span>IOPL <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>IOPL<span class="operator">;</span>
<span class="keyword">if</span><span class="operator">(</span>OperandSize <span class="operator">==</span> <span class="number">32</span><span class="operator">)</span> {
EFLAGS<span class="operator">.</span>VM <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>VM<span class="operator">;</span>
EFLAGS<span class="operator">.</span>VIF <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>VIF<span class="operator">;</span>
EFLAGS<span class="operator">.</span>VIP <span class="operator">=</span> TemporaryEFLAGS<span class="operator">.</span>VIP<span class="operator">;</span>
}
}
<span class="comment">//END</span>
}
}
}
</pre>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Flags affected</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<p>All the flags and fields in the EFLAGS register are potentially modified, depending on the mode of operation of the processor. If performing a return from a nested task to a previous task, the EFLAGS register will be modified according to the EFLAGS image stored in the previous task's TSS.
</p>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Protected Mode Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<div>
<table class="operations_table">
<tr><td><code>#GP(0)</code></td><td>If the return code or stack segment selector is null. If the return instruction pointer is not within the return code segment limit.</td></tr>
<tr><td><code>#GP(0)</code></td><td>If the return code or stack segment selector is null. If the return instruction pointer is not within the return code segment limit.</td></tr>
<tr><td><code>#GP(selector)</code></td><td>If a segment selector index is outside its descriptor table limits. If the return code segment selector RPL is greater than the CPL. If the DPL of a conforming-code segment is greater than the return code segment selector RPL. If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment selector. If the stack segment descriptor DPL is not equal to the RPL of the return code segment selector. If the stack segment is not a writable data segment. If the stack segment selector RPL is not equal to the RPL of the return code segment selector. If the segment descriptor for a code segment does not indicate it is a code segment. If the segment selector for a TSS has its local/global bit set for local. If a TSS segment descriptor specifies that the TSS is not busy. If a TSS segment descriptor specifies that the TSS is not available.</td></tr>
<tr><td><code>#SS(0)</code></td><td>If the top bytes of stack are not within stack limits.</td></tr>
<tr><td><code>#NP(selector)</code></td><td>If the return code or stack segment is not present.</td></tr>
<tr><td><code>#PF(fault-code)</code></td><td>If a page fault occurs.</td></tr>
</table>
</div>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Real-Address Mode Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<div>
<table class="operations_table">
<tr><td><code>#GP</code></td><td>If the return instruction pointer is not within the return code segment limit.</td></tr>
<tr><td><code>#GP</code></td><td>If the return instruction pointer is not within the return code segment limit.</td></tr>
</table>
</div>
</td>
</tr>
</table>
</object>
<object>
<table class="box">
<tr>
<th>Virtual-8086 Mode Exceptions</th>
</tr>
<tr>
<td class="instruction_set_reference_box">
<div>
<table class="operations_table">
<tr><td><code>#GP(0)</code></td><td>If the return instruction pointer is not within the return code segment limit. IF IOPL not equal to 3.</td></tr>
<tr><td><code>#GP(0)</code></td><td>If the return instruction pointer is not within the return code segment limit. IF IOPL not equal to 3.</td></tr>
<tr><td><code>#PF(fault-code)</code></td><td>If a page fault occurs.</td></tr>
<tr><td><code>#SS(0)</code></td><td>If the top bytes of stack are not within stack limits.</td></tr>
</table>
</div>
</td>
</tr>
</table>
</object>
</div>
</body>
</html>