⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interrupt-handling_4.htm

📁 编写自己的操作系统
💻 HTM
📖 第 1 页 / 共 3 页
字号:
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>&nbsp;</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>&nbsp;</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>&nbsp;</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>&nbsp;</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&nbsp;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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __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>&nbsp;</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>&nbsp;</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&nbsp;Task Restart</STRONG><SPAN lang=EN-US><FONT 
face="Times New Roman" size=5><SPAN style="mso-tab-count: 1">&nbsp;</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 + -