| INT |
| Прекъсване |
| Общи форми: |
INT interrupt |
| Форма |
КОП |
CPUID |
I8086 |
I80386 |
I80486 |
| 16 |
32 |
64 |
Alt |
|
I8086 |
I80386 |
I80486 |
| INT ib |
CD ib |
CD ib |
CD ib |
DC ib |
същото ниво по-високо ниво задача |
51 |
37; pm=59 pm=99; vm=119 pm/vm=ts |
30; pm=44 pm=71; vm=66 pm/vm=37+ts |
|
| Действие |
IF PE = 0 THEN
push(eFLAGS)
push(CS)
push(eIP)
eIP ← IDTR.Base[interrupt * 4]
eIP ← IDTR.Base[interrupt * 4 + 2]
IF ← 0
CacheDescriptor(CS)
ELSE (* защитен режим *)
IF (инструкция IS INT)
AND (VM = 1) (* режим V86 *)
AND (CR4.VME = 1) (* разрешени разширения *)
AND (TSS IS 32-bit)
AND (TSS.IOPM ≠ 0) (* има карта за пренасочване *)
AND (TSS[TSS.IOPM-8]{interrupt} = 0) (* пренасочване *)
THEN
IF IOPL = 3 THEN
temp ← EFLAGS
temp.IOPL ← 0
temp.NT ← 0
push(temp)
IF ← 0
ELSE
temp ← EFLAGS
temp.IOPL ← 3
temp.IF ← VIF
push(temp)
VIF ← 0
ENDIF
push(CS)
push(eIP)
eIP ← [0000: interrupt * 4]
CS ← [0000: interrupt * 4 + 2]
CacheDescriptor(CS)
ELSE
CASE Gate OF
Task-gate:
SwitchTasks(link)
Int-gate, Trap-gate:
IF 64-Bit Mode THEN
push(SS)
push(RSP)
IF CPL > new PL THEN
IF Gate.IST = 0 THEN
RSP ← TSS.RSP[new PL]
ELSE
RSP ← TSS.IST[Gate.IST]
ENDIF
ENDIF
SS ← 0
ELSE
IF CPL > new PL THEN
SaveSS ← SS
SaveESP ← eSP
SS ← TSS.SS[new PL]
ESP ← TSS.ESP[new PL]
ENDIF
IF VM = 1 THEN
IF new PL > 0 THEN #GP(0)
FOR xS in (GS, FS, DS, ES) DO
push(xS)
xS ← 0
NEXT
ENDIF
push(SaveSS)
push(SaveESP)
ENDIF
push(eFLAGS)
push(eIP)
push(CS)
VM ← 0
NT ← 0
EIP ← Gate.Offset
CS ← Gate.Selector
CacheDescriptor(CS)
IF Gate IS Int-gate THEN
IF ← 0
ENDIF
ELSE
#GP(constant + I + E)
END CASE
IF обработка на изключение с код на грешка THEN
push(код)
ENDIF
ENDIF
ENDIF
IF обработка на NMI THEN
маскира вътрешно NMI
ENDIF
TF ← 0
|
| Забележка: |
Забележка: по този алгоритъм се извиква външно прекъсване (по линия NMI или по линия IRQ, ако IF=1), изключение и програмно прекъсване.
|
| Флагове |
| PE |
VM |
NT |
IOPL |
OF |
DF |
IF |
TF |
SF |
ZF |
AF |
PF |
CF |
| T |
TS0 |
S0 |
TS |
S |
S |
SF |
S0 |
S |
S |
S |
S |
S |
|
| CPU |
| 8086 |
186 |
V20 |
286 |
386 |
486 |
P |
P-P |
P-II |
MMX |
SSE |
3D! |
E64 |
| • |
• |
• |
• |
• |
• |
• |
• |
• |
• |
|
|
• |
|
| Изключения |
ПАМЕТ +
| Реален режим: |
| #GP |
IDT не съдържа дескриптор за прекъсването |
| Защитен режим: |
| #GP(interrupt+I+E) |
IDT не съдържа дескриптор за прекъсването |
| #GP(interrupt+I+E) |
Дескрипторът не изход за капан, прекъсване или задача |
| #GP(interrupt+I+E) |
DPL на изхода < CPL |
| #NP(interrupt+I+E) |
Дескрипторът в IDT е отбелязан като неприсъстващ |
| #SS(selector+E) |
Новият стек е невалиден |
| #SS(selector+E) |
В новия стек няма място за всички данни (CS:eIP, SS:eIP, код на грешка) |
| #GP(selector+E) |
Дескрипторът на новия кодов сегмент е извън таблицата |
| #GP(selector+E) |
Селекторът в изхода не избира кодов сегмент |
| #GP(selector+E) |
Новият кодов сегмент е несъвместим и DPL > CPL |
| #NP(selector+E) |
Новият кодов сегмент е отбелязан като неприсъстващ |
| #GP(0+E) |
Целевото отместване е извън кодовия сегмент |
| #DF(0) |
Грешка при обработка на #TS, #NP, #SS, #GP, #PF |
| 3ER |
Грешка при обработка на #DF |
| Изключения при превключване на задача |
| Режим V86 |
| #GP(0+E) |
IOPL < CPL (инструкция INT) |
| #GP(0+E) |
DPL на новия кодов сегмент > 0 |
| Останалите изключения са като в защитен режим |
|