* better
[mascara-docs.git] / hw / i386.reference / IRET.htm
blob1dbcb3d4d4a34105ee0fce84b0c5d6c0efaa3ac1
1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
2 <HTML>
3 <HEAD>
4 <TITLE>80386 Programmer's Reference Manual -- Opcode IRET</TITLE>
5 </HEAD>
6 <BODY>
7 <B>up:</B> <A HREF="c17.htm">
8 Chapter 17 -- 80386 Instruction Set</A><BR>
9 <B>prev:</B><A HREF="INT.htm"> INT/INTO Call to Interrupt Procedure</A><BR>
10 <B>next:</B><A HREF="Jcc.htm"> Jcc Jump if Condition is Met</A>
11 <P>
12 <HR>
13 <P>
14 <H1>IRET/IRETD -- Interrupt Return</H1>
16 <PRE>
17 Opcode Instruction Clocks Description
19 CF IRET 22,pm=38 Interrupt return (far return and pop
20 flags)
21 CF IRET pm=82 Interrupt return to lesser privilege
22 CF IRET ts Interrupt return, different task (NT = 1)
23 CF IRETD 22,pm=38 Interrupt return (far return and pop
24 flags)
25 CF IRETD pm=82 Interrupt return to lesser privilege
26 CF IRETD pm=60 Interrupt return to V86 mode
27 CF IRETD ts Interrupt return, different task (NT = 1)
28 </PRE>
30 <EM>
31 </H3>Note</H3>
32 Values of ts are given by the following table:
34 <PRE>
35 New Task
37 Old Task 386 TSS 386 TSS 286 TSS
38 VM = 0 VM = 1
40 386
41 TSS VM=0 275 224 271
43 286
44 TSS 265 214 232
45 </PRE>
46 </EM>
48 <H2>Operation</H2>
50 <PRE>
51 IF PE = 0
52 THEN (* Real-address mode *)
53 IF OperandSize = 32 (* Instruction = IRETD *)
54 THEN EIP := Pop();
55 ELSE (* Instruction = IRET *)
56 IP := Pop();
57 FI;
58 CS := Pop();
59 IF OperandSize = 32 (* Instruction = IRETD *)
60 THEN EFLAGS := Pop();
61 ELSE (* Instruction = IRET *)
62 FLAGS := Pop();
63 FI;
64 ELSE (* Protected mode *)
65 IF VM = 1
66 THEN #GP(0);
67 ELSE
68 IF NT = 1
69 THEN GOTO TASK-RETURN;
70 ELSE
71 IF VM = 1 in flags image on stack
72 THEN GO TO STACK-RETURN-TO-V86;
73 ELSE GOTO STACK-RETURN;
74 FI;
75 FI;
76 FI;
77 FI;STACK-RETURN-TO-V86: (* Interrupted procedure was in V86 mode *)
78 IF return CS selector RPL < > 3
79 THEN #GP(Return selector);
80 FI;
81 IF top 36 bytes of stack not within limits
82 THEN #SS(0);
83 FI;
84 Examine return CS selector and associated descriptor:
85 IF selector is null, THEN #GP(0); FI;
86 IF selector index not within its descriptor table limits;
87 THEN #GP(Return selector);
88 FI;
89 IF AR byte does not indicate code segment
90 THEN #GP(Return selector);
91 FI;
92 IF code segment DPL not = 3;
93 THEN #GP(Return selector);
94 FI;
95 IF code segment not present
96 THEN #NP(Return selector);
97 FI;
99 Examine return SS selector and associated descriptor:
100 IF selector is null THEN #GP(0); FI;
101 IF selector index not within its descriptor table limits
102 THEN #GP(SS selector);
104 IF selector RPL not = RPL of return CS selector
105 THEN #GP(SS selector);
107 IF AR byte does not indicate a writable data segment
108 THEN #GP(SS selector);
110 IF stack segment DPL not = RPL of return CS selector
111 THEN #GP(SS selector);
113 IF SS not present
114 THEN #NP(SS selector);
117 IF instruction pointer not within code segment limit THEN #GP(0);
119 EFLAGS := SS:[eSP + 8]; (* Sets VM in interrupted routine *)
120 EIP := Pop();
121 CS := Pop(); (* CS behaves as in 8086, due to VM = 1 *)
122 throwaway := Pop(); (* pop away EFLAGS already read *)
123 ES := Pop(); (* pop 2 words; throw away high-order word *)
124 DS := Pop(); (* pop 2 words; throw away high-order word *)
125 FS := Pop(); (* pop 2 words; throw away high-order word *)
126 GS := Pop(); (* pop 2 words; throw away high-order word *)
127 IF CS.RPL > CPL
128 THEN
129 TempESP := Pop();
130 TempSS := Pop();
131 SS:ESP := TempSS:TempESP;
134 (* Resume execution in Virtual 8086 mode *)
136 TASK-RETURN:
137 Examine Back Link Selector in TSS addressed by the current task
138 register:
139 Must specify global in the local/global bit, else #TS(new TSS
140 selector);
141 Index must be within GDT limits, else #TS(new TSS selector);
142 AR byte must specify TSS, else #TS(new TSS selector);
143 New TSS must be busy, else #TS(new TSS selector);
144 TSS must be present, else #NP(new TSS selector);
145 SWITCH-TASKS without nesting to TSS specified by back link selector;
146 Mark the task just abandoned as NOT BUSY;
147 Instruction pointer must be within code segment limit ELSE #GP(0);
149 STACK-RETURN:
150 IF OperandSize=32
151 THEN Third word on stack must be within stack limits, else #SS(0);
152 ELSE Second word on stack must be within stack limits, else #SS(0);
154 Return CS selector RPL must be >= CPL, else #GP(Return selector);
155 IF return selector RPL = CPL
156 THEN GOTO RETURN-SAME-LEVEL;
157 ELSE GOTO RETURN-OUTER-LEVEL;
160 RETURN-SAME-LEVEL:
161 IF OperandSize=32
162 THEN
163 Top 12 bytes on stack must be within limits, else #SS(0);
164 Return CS selector (at eSP+4) must be non-null, else #GP(0);
165 ELSE
166 Top 6 bytes on stack must be within limits, else #SS(0);
167 Return CS selector (at eSP+2) must be non-null, else #GP(0);
169 Selector index must be within its descriptor table limits, else #GP
170 (Return selector);
171 AR byte must indicate code segment, else #GP(Return selector);
172 IF non-conforming
173 THEN code segment DPL must = CPL;
174 ELSE #GP(Return selector);
176 IF conforming
177 THEN code segment DPL must be <= CPL, else #GP(Return selector);
178 Segment must be present, else #NP(Return selector);
179 Instruction pointer must be within code segment boundaries, else #GP(0);
181 IF OperandSize=32
182 THEN
183 Load CS:EIP from stack;
184 Load CS-register with new code segment descriptor;
185 Load EFLAGS with third doubleword from stack;
186 Increment eSP by 12;
187 ELSE
188 Load CS-register with new code segment descriptor;
189 Load FLAGS with third word on stack;
190 Increment eSP by 6;
193 RETURN-OUTER-LEVEL:
194 IF OperandSize=32
195 THEN Top 20 bytes on stack must be within limits, else #SS(0);
196 ELSE Top 10 bytes on stack must be within limits, else #SS(0);
198 Examine return CS selector and associated descriptor:
199 Selector must be non-null, else #GP(0);
200 Selector index must be within its descriptor table limits;
201 ELSE #GP(Return selector);
202 AR byte must indicate code segment, else #GP(Return selector);
203 IF non-conforming
204 THEN code segment DPL must = CS selector RPL;
205 ELSE #GP(Return selector);
207 IF conforming
208 THEN code segment DPL must be > CPL;
209 ELSE #GP(Return selector);
211 Segment must be present, else #NP(Return selector);
212 Examine return SS selector and associated descriptor:
213 Selector must be non-null, else #GP(0);
214 Selector index must be within its descriptor table limits
215 ELSE #GP(SS selector);
216 Selector RPL must equal the RPL of the return CS selector
217 ELSE #GP(SS selector);
218 AR byte must indicate a writable data segment, else #GP(SS selector);
219 Stack segment DPL must equal the RPL of the return CS selector
220 ELSE #GP(SS selector);
221 SS must be present, else #NP(SS selector);
223 Instruction pointer must be within code segment limit ELSE #GP(0);
224 IF OperandSize=32
225 THEN
226 Load CS:EIP from stack;
227 Load EFLAGS with values at (eSP+8);
228 ELSE
229 Load CS:IP from stack;
230 Load FLAGS with values at (eSP+4);
232 Load SS:eSP from stack;
233 Set CPL to the RPL of the return CS selector;
234 Load the CS register with the CS descriptor;
235 Load the SS register with the SS descriptor;
236 FOR each of ES, FS, GS, and DS
238 IF the current value of the register is not valid for the outer level;
239 THEN zero the register and clear the valid flag;
241 To be valid, the register setting must satisfy the following
242 properties:
243 Selector index must be within descriptor table limits;
244 AR byte must indicate data or readable code segment;
245 IF segment is data or non-conforming code,
246 THEN DPL must be >= CPL, or DPL must be >= RPL;
248 </PRE>
250 <H2>Description</H2>
252 In Real Address Mode, IRET pops the instruction pointer, CS, and the
253 flags register from the stack and resumes the interrupted routine.
255 In Protected Mode, the action of IRET depends on the setting of the
256 nested task flag (NT) bit in the flag register. When popping the new
257 flag image from the stack, the IOPL bits in the flag register are changed
258 only when CPL equals 0.
260 If NT equals 0, IRET returns from an interrupt procedure without a
261 task switch. The code returned to must be equally or less privileged than
262 the interrupt routine (as indicated by the RPL bits of the CS selector
263 popped from the stack). If the destination code is less privileged, IRET
264 also pops the stack pointer and SS from the stack.
266 If NT equals 1, IRET reverses the operation of a
267 <A HREF="CALL.htm">CALL</A> or <A HREF="INT.htm">INT</A> that
268 caused a task switch. The updated state of the task executing IRET is
269 saved in its task state segment. If the task is reentered later, the code
270 that follows IRET is executed.
272 <H2>Flags Affected</H2>
274 All; the flags register is popped from stack
276 <H2>Protected Mode Exceptions</H2>
278 #GP, #NP, or #SS, as indicated under "<H2>Operation</H2>" above
280 <H2>Real Address Mode Exceptions</H2>
282 Interrupt 13 if any part of the operand being popped lies beyond address
283 0FFFFH
285 <H2>Virtual 8086 Mode Exceptions</H2>
287 #GP(0) fault if IOPL is less than 3, to permit emulation
291 <HR>
293 <B>up:</B> <A HREF="c17.htm">
294 Chapter 17 -- 80386 Instruction Set</A><BR>
295 <B>prev:</B><A HREF="INT.htm"> INT/INTO Call to Interrupt Procedure</A><BR>
296 <B>next:</B><A HREF="Jcc.htm"> Jcc Jump if Condition is Met</A>
297 </BODY>