📄 interrupt-handling_4.htm
字号:
flag,是为了避免Instruction tracing影响中断的响应。随后的IRET指令会从栈中的EFLAGS中恢复TF
flag的值。</SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1">在Interrupt Gate和Trap
Gate之间的唯一区别是,当通过一个Interrupt
Gate来处理一个Interrupt/Exception时,CPU会在将EFLAGS压栈之后,清除EFLAGS寄存器的IF flag。清除IF
flag,是为了避免在当前ISR执行时受到其它Interrupts的影响。随后的IRET指令会从栈中的EFLAGS中恢复IF flag的值。而通过Trap
Gate来处理Interrupt/Exception则不会影响IF
flag的设置。</SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">需要注意的是,在恢复EFLAGS的时候,只有CPL=0的时候,IOPL域才能够被恢复;只有CPL在数值上小于或等于IOPL时,IF位才能够被恢复。</SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">下面是用C++实现的IRET指令:</SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">inline
void iret(void)</SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">{</SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"> __asm__
__volatile__ ("iret": :
:"memory");</SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">}</SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN></SPAN></FONT></SPAN> </P><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1"><SPAN lang=EN-US><FONT face="Times New Roman TUR"
size=3><SPAN style="mso-tab-count: 1"><SPAN lang=EN-US><FONT
face="Times New Roman TUR" size=3><SPAN style="mso-tab-count: 1"><SPAN
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN
style="mso-tab-count: 1">
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><FONT size=4><STRONG>Task Gate</STRONG></FONT></P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><FONT face=宋体><FONT face="Times New Roman TUR"><FONT
face=宋体></FONT></FONT></FONT> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"
align=left><FONT face=宋体><FONT face="Times New Roman TUR"><FONT
face=宋体>如果</FONT></FONT><FONT face="Times New Roman TUR">调用Task
Gate</FONT>,会引起<FONT face="Times New Roman TUR">Context</FONT>切换。如果<FONT
face="Times New Roman TUR">Interrupts/Exceptions</FONT>使用这种方式的话,会有如下几个优点:</FONT></P><FONT
face=宋体>
<UL>
<LI>被中断的程序的<FONT face="Times New Roman TUR">Context</FONT>会被完全被保存;
<LI>允许<FONT face="Times New Roman TUR">ISR</FONT>使用新的<FONT
face="Times New Roman TUR">CPL</FONT>为<FONT
face="Times New Roman TUR">0</FONT>的<FONT
face="Times New Roman TUR">stack</FONT>;这样如果<FONT
face="Times New Roman TUR">Interrupt/Exception</FONT>是由于内核<FONT
face="Times New Roman TUR">stack</FONT>越界引起的话,可以通过<FONT
face="Times New Roman TUR">TSS</FONT>指定的新的<FONT
face="Times New Roman TUR">CPL=0</FONT>的<FONT
face="Times New Roman TUR">stack</FONT>来解决这个故障,而不是让系统崩溃;
<LI>
<P><FONT
face="Times New Roman TUR">ISR</FONT>可以被放在一个独立的地址空间中,这种情况下,你需要通过设定一个独立的<FONT
face="Times New Roman TUR">LDT</FONT>。</P></LI></UL>
<P>但也必须注意它的缺点:由于在任务切换时,当时的机器状态需要全部被保存,所以它的性能要比<FONT
face="Times New Roman TUR">Interrupt Gate</FONT>和<FONT
face="Times New Roman TUR">Trap Gate</FONT>低。从而导致中断延迟越来越多。</P>
<DIV>将<FONT face="Times New Roman TUR">ISR</FONT>作为一个<FONT
face="Times New Roman TUR">Task</FONT>,然后通过<FONT face="Times New Roman TUR">Task
Gate</FONT>实现从被中断任务向<FONT face="Times New Roman TUR">ISR
Task</FONT>的切换,与普通的任务切换没有什么两样。我们注意到,在<FONT face="Times New Roman TUR">Task Gate
Descriptor</FONT>中,一个主要的元素就是</FONT><FONT face="Times New Roman TUR">TSS Segment
Selector</FONT><FONT face=宋体>,这个<FONT
face="Times New Roman TUR">Selector</FONT>指向一个存放在<FONT
face="Times New Roman TUR">GDT</FONT>中的<FONT face="Times New Roman TUR">TSS
Descriptor</FONT>。它所指向的<FONT face="Times New Roman TUR">TSS</FONT>是供<FONT
face="Times New Roman TUR">ISR Task</FONT>使用的。这个<FONT
face="Times New Roman TUR">TSS</FONT>中的<FONT face="Times New Roman TUR">Previous
Task Link</FONT>域指向那个被中断任务的<FONT face="Times New Roman TUR">TSS</FONT>。如果<FONT
face="Times New Roman TUR">Exception</FONT>返回一个<FONT
face="Times New Roman TUR">error code</FONT>的话,那么<FONT
face="Times New Roman TUR">error code</FONT>会被保存在<FONT
face="Times New Roman TUR">ISR Task</FONT>的<FONT
face="Times New Roman TUR">stack</FONT>中。</FONT></DIV>
<P align=center><IMG src="interrupt-handling_4.files/task_gate.gif"
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/handling/task_gate.gif"></P>
<HR width="100%" SIZE=2>
<P><SPAN lang=EN-US><FONT face="Times New Roman"><SPAN
style="mso-tab-count: 1"><FONT face="Times New Roman TUR"
size=5><STRONG>2.4.3 Task Restart</STRONG><SPAN lang=EN-US><FONT
face="Times New Roman" size=5><SPAN style="mso-tab-count: 1"> </P>
<P class=MsoNormal
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3"><SPAN
lang=EN-US><FONT face="Times New Roman" size=5><SPAN
style="mso-tab-count: 1"><FONT face=宋体><FONT size=+0><FONT size=3><FONT
face="Times New Roman TUR">为了能够保证一个被中断的Task能够在ISR运行结束后继续运行,除了Aborts之外的其他Exceptions,会保证在引起异常的精确指令位置来触发这个Exception。而所有的Interrupts则保证在一个指令结束后才会被触发。也就是说Interrupts/Exceptions都不会破坏指令的原子性。</FONT></FONT></FONT></FONT></SPAN></FONT></SPAN></P>
<P class=MsoNormal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -