-
Notifications
You must be signed in to change notification settings - Fork 29
/
INT.htm
291 lines (260 loc) · 9.9 KB
/
INT.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML>
<HEAD>
<TITLE>80386 Programmer's Reference Manual -- Opcode INT</TITLE>
</HEAD>
<BODY STYLE="width:80ch">
<B>up:</B> <A HREF="c17.htm">
Chapter 17 -- 80386 Instruction Set</A><BR>
<B>prev:</B><A HREF="INS.htm"> INS/INSB/INSW/INSD Input from Port to String</A><BR>
<B>next:</B><A HREF="IRET.htm"> IRET/IRETD Interrupt Return</A>
<P>
<HR>
<P>
<H1>INT/INTO -- Call to Interrupt Procedure</H1>
<PRE>
Opcode Instruction Clocks Description
CC INT 3 33 Interrupt 3--trap to debugger
CC INT 3 pm=59 Interrupt 3--Protected Mode, same
privilege
CC INT 3 pm=99 Interrupt 3--Protected Mode, more
privilege
CC INT 3 pm=119 Interrupt 3--from V86 mode to PL 0
CC INT 3 ts Interrupt 3--Protected Mode, via
task gate
CD ib INT imm8 37 Interrupt numbered by immediate
byte
CD ib INT imm8 pm=59 Interrupt--Protected Mode, same
privilege
CD ib INT imm8 pm=99 Interrupt--Protected Mode, more
privilege
CD ib INT imm8 pm=119 Interrupt--from V86 mode to PL 0
CD ib INT imm8 ts Interrupt--Protected Mode, via task
gate
CE INTO Fail:3,pm=3;
Pass:35 Interrupt 4--if overflow flag is 1
CE INTO pm=59 Interrupt 4--Protected Mode, same
privilege
CE INTO pm=99 Interrupt 4--Protected Mode, more
privilege
CE INTO pm=119 Interrupt 4--from V86 mode to PL 0
CE INTO ts Interrupt 4--Protected Mode, via
task gate
</PRE>
<EM>
<H3>Note</H3>
Approximate values of ts are given by the following table:
<PRE>
New Task
Old Task 386 TSS 386 TSS 286 TSS
VM = 0 VM = 1
386
TSS VM=0 309 226 282
386
TSS VM=1 314 231 287
286
TSS 307 224 280
</PRE>
</EM>
<H2>Operation</H2>
<EM>
<H3>Note</H3>
The following operational description applies not only to the
above instructions but also to external interrupts and exceptions.
</EM>
<PRE>
IF PE = 0
THEN GOTO REAL-ADDRESS-MODE;
ELSE GOTO PROTECTED-MODE;
FI;
REAL-ADDRESS-MODE:
Push (FLAGS);
IF = 0; (* Clear interrupt flag *)
TF = 0; (* Clear trap flag *)
Push(CS);
Push(IP);
(* No error codes are pushed *)
CS := IDT[Interrupt number * 4].selector;
IP := IDT[Interrupt number * 4].offset;
PROTECTED-MODE:
Interrupt vector must be within IDT table limits,
else #GP(vector number * 8+2+EXT);
Descriptor AR byte must indicate interrupt gate, trap gate, or task gate,
else #GP(vector number * 8+2+EXT);
IF software interrupt (* i.e. caused by INT n, INT 3, or INTO *)
THEN
IF gate descriptor DPL < CPL
THEN #GP(vector number * 8+2+EXT);
FI;
FI;
Gate must be present, else #NP(vector number * 8+2+EXT);
IF trap gate OR interrupt gate
THEN GOTO TRAP-GATE-OR-INTERRUPT-GATE;
ELSE GOTO TASK-GATE;
FI;
TRAP-GATE-OR-INTERRUPT-GATE:
Examine CS selector and descriptor given in the gate descriptor;
Selector must be non-null, else #GP (EXT);
Selector must be within its descriptor table limits
ELSE #GP(selector+EXT);
Descriptor AR byte must indicate code segment
ELSE #GP(selector + EXT);
Segment must be present, else #NP(selector+EXT);
IF code segment is non-conforming AND DPL < CPL
THEN GOTO INTERRUPT-TO-INNER-PRIVILEGE;
ELSE
IF code segment is conforming OR code segment DPL = CPL
THEN GOTO INTERRUPT-TO-SAME-PRIVILEGE-LEVEL;
ELSE #GP(CS selector + EXT);
FI;
FI;
INTERRUPT-TO-INNER-PRIVILEGE:
Check selector and descriptor for new stack in current TSS;
Selector must be non-null, else #GP(EXT);
Selector index must be within its descriptor table limits
ELSE #TS(SS selector+EXT);
Selector's RPL must equal DPL of code segment, else #TS(SS
selector+EXT);
Stack segment DPL must equal DPL of code segment, else #TS(SS
selector+EXT);
Descriptor must indicate writable data segment, else #TS(SS
selector+EXT);
Segment must be present, else #SS(SS selector+EXT);
IF 32-bit gate
THEN New stack must have room for 20 bytes else #SS(0)
ELSE New stack must have room for 10 bytes else #SS(0)
FI;
Instruction pointer must be within CS segment boundaries else #GP(0);
Load new SS and eSP value from TSS;
IF 32-bit gate
THEN CS:EIP := selector:offset from gate;
ELSE CS:IP := selector:offset from gate;
FI;
Load CS descriptor into invisible portion of CS register;
Load SS descriptor into invisible portion of SS register;
IF 32-bit gate
THEN
Push (long pointer to old stack) (* 3 words padded to 4 *);
Push (EFLAGS);
Push (long pointer to return location) (* 3 words padded to 4*);
ELSE
Push (long pointer to old stack) (* 2 words *);
Push (FLAGS);
Push (long pointer to return location) (* 2 words *);
FI;
Set CPL to new code segment DPL;
Set RPL of CS to CPL;
IF interrupt gate THEN IF = 0 (* interrupt flag to 0 (disabled) *); FI;
TF := 0;
NT := 0;
INTERRUPT-FROM-V86-MODE:
TempEFlags := EFLAGS;
VM := 0;
TF := 0;
IF service through Interrupt Gate THEN IF = 0;
TempSS := SS;
TempESP := ESP;
SS := TSS.SS0; (* Change to level 0 stack segment *)
ESP := TSS.ESP0; (* Change to level 0 stack pointer *)
Push(GS); (* padded to two words *)
Push(FS); (* padded to two words *)
Push(DS); (* padded to two words *)
Push(ES); (* padded to two words *)
GS := 0;
FS := 0;
DS := 0;
ES := 0;
Push(TempSS); (* padded to two words *)
Push(TempESP);
Push(TempEFlags);
Push(CS); (* padded to two words *)
Push(EIP);
CS:EIP := selector:offset from interrupt gate;
(* Starts execution of new routine in 80386 Protected Mode *)
INTERRUPT-TO-SAME-PRIVILEGE-LEVEL:
IF 32-bit gate
THEN Current stack limits must allow pushing 10 bytes, else #SS(0);
ELSE Current stack limits must allow pushing 6 bytes, else #SS(0);
FI;
IF interrupt was caused by exception with error code
THEN Stack limits must allow push of two more bytes;
ELSE #SS(0);
FI;
Instruction pointer must be in CS limit, else #GP(0);
IF 32-bit gate
THEN
Push (EFLAGS);
Push (long pointer to return location); (* 3 words padded to 4 *)
CS:EIP := selector:offset from gate;
ELSE (* 16-bit gate *)
Push (FLAGS);
Push (long pointer to return location); (* 2 words *)
CS:IP := selector:offset from gate;
FI;
Load CS descriptor into invisible portion of CS register;
Set the RPL field of CS to CPL;
Push (error code); (* if any *)
IF interrupt gate THEN IF = 0; FI;
TF := 0;
NT := 0;
TASK-GATE:
Examine selector to TSS, given in task gate descriptor;
Must specify global in the local/global bit, else #TS(TSS selector);
Index must be within GDT limits, else #TS(TSS selector);
AR byte must specify available TSS (bottom bits 00001),
else #TS(TSS selector;
TSS must be present, else #NP(TSS selector);
SWITCH-TASKS with nesting to TSS;
IF interrupt was caused by fault with error code
THEN
Stack limits must allow push of two more bytes, else #SS(0);
Push error code onto stack;
FI;
Instruction pointer must be in CS limit, else #GP(0);
</PRE>
<H2>Description</H2>
The INT instruction generates via software a call to an interrupt
handler. The immediate operand, from 0 to 255, gives the index number
into the Interrupt Descriptor Table (IDT) of the interrupt routine to be
called. In Protected Mode, the IDT consists of an array of eight-byte
descriptors; the descriptor for the interrupt invoked must indicate an
interrupt, trap, or task gate. In Real Address Mode, the IDT is an array
of four byte-long pointers. In Protected and Real Address Modes, the
base linear address of the IDT is defined by the contents of the IDTR.
<P>
The INTO conditional software instruction is identical to the INT
interrupt instruction except that the interrupt number is implicitly 4,
and the interrupt is made only if the 80386 overflow flag is set.
<P>
The first 32 interrupts are reserved by Intel for system use. Some of
these interrupts are use for internally generated exceptions.
<P>
INT n generally behaves like a far call except that the flags register is
pushed onto the stack before the return address. Interrupt procedures
return via the
<A HREF="IRET.htm">IRET</A>
instruction, which pops the flags and return address
from the stack.
<P>
In Real Address Mode, INT n pushes the flags, CS, and the return IP
onto the stack, in that order, then jumps to the long pointer indexed by
the interrupt number.
<H2>Flags Affected</H2>
None
<H2>Protected Mode Exceptions</H2>
#GP, #NP, #SS, and #TS as indicated under "<H2>Operation</H2>" above
<H2>Real Address Mode Exceptions</H2>
None; if the SP or ESP = 1, 3, or 5 before executing INT or INTO,
the 80386 will shut down due to insufficient stack space
<H2>Virtual 8086 Mode Exceptions</H2>
#GP(0) fault if IOPL is less than 3, for INT only, to permit emulation;
Interrupt 3 (0CCH) generates Interrupt 3; INTO generates Interrupt 4
if the overflow flag equals 1
<P>
<HR>
<P>
<B>up:</B> <A HREF="c17.htm">
Chapter 17 -- 80386 Instruction Set</A><BR>
<B>prev:</B><A HREF="INS.htm"> INS/INSB/INSW/INSD Input from Port to String</A><BR>
<B>next:</B><A HREF="IRET.htm"> IRET/IRETD Interrupt Return</A>
</BODY>