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

📄 interrupt-handling_4.htm

📁 编写自己的操作系统
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0063)http://www.huihoo.com/gnu_linux/own_os/interrupt-handling_4.htm -->
<HTML><HEAD><TITLE></TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><FONT 
face="Times New Roman" size=6><SPAN style="mso-tab-count: 1"><STRONG>2.4 
Handling &amp; Error Code</STRONG></SPAN></FONT></SPAN></P><SPAN 
lang=EN-US><FONT face="Times New Roman" size=5><SPAN style="mso-tab-count: 1">
<P>
<P><FONT size=3>[</FONT><A 
href="index.htm" 
tppabs="http://pagoda-ooos.51.net/os_book/index.htm"><FONT 
size=3>Home</FONT></A><FONT size=3>]&nbsp; [</FONT><A 
href="interrupt_and_exception.htm" 
tppabs="http://pagoda-ooos.51.net/os_book/interrupt_and_exception.htm"><FONT 
size=3>Top</FONT></A><FONT size=3>]&nbsp; [</FONT><A 
href="interrupt-priority_3.htm" 
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/interrupt-priority_3.htm"><FONT 
size=3>Previous</FONT></A><FONT size=3>]&nbsp; [</FONT><FONT size=3><A 
href="interrupt-8259_5.htm" 
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/interrupt-handling_4.htm">Next</A>]</FONT></P>
<P><STRONG>
<HR width="100%" SIZE=2>
</STRONG>
<P></P>
<P></P></SPAN></FONT></SPAN><SPAN lang=EN-US><FONT face="Times New Roman" 
size=5><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"><FONT 
face="Times New Roman TUR" size=5><STRONG>2.4.1 Overview</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"><SPAN 
lang=EN-US><FONT face="Times New Roman" size=5><SPAN 
style="mso-tab-count: 1"><FONT face=宋体><FONT size=3><FONT 
face="Times New Roman TUR"></FONT></FONT></FONT></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"><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">当一个Interrupt/Exception发生时,CPU将以这个Interrupt/Exception的Vector 
Number为索引,到IDT中查找相应的Gate Descriptor。IDT中的Gate Descriptor有3种:Interrupt Gate 
Descriptor,Trap Gate Descriptor,Task Gate Descriptor。根据被设置的Gate 
Descriptor的不同,对ISR的调用方法和处理过程也不同。</FONT></FONT></FONT></FONT></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1">当某些Exceptions发生时,会返回Error 
Code,以通知相应的ISR是那个Segment引起了这个Exception。</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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"><STRONG><FONT face="Times New Roman" size=5>&nbsp;</P>
<HR width="100%" SIZE=2>
</FONT></STRONG>
<P></P>
<P><STRONG><FONT face="Times New Roman" size=5></FONT></STRONG></P><SPAN 
lang=EN-US><FONT face="Times New Roman" size=5><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"><FONT 
face="Times New Roman TUR"><STRONG>2.4.2 ISR Handling</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"><SPAN 
lang=EN-US><FONT face="Times New Roman" size=5><SPAN 
style="mso-tab-count: 1"><FONT face=宋体><FONT size=3><FONT 
face="Times New Roman TUR"></FONT></FONT></FONT></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"><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">一个ISR(Interrupt Service 
Routine)是一块专门用来处理某个Interrupt/Exception的程序。</FONT></FONT></FONT></FONT></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1">如果一个Interrupt/Exception引用的是一个Interrupt Gate或Trap 
Gate,则当这个Interrupt/Exception发生时,不发生任务切换,其ISR仍然引用当前任务的Context。Interrupt/Trap Gate 
Descriptor中的Segment 
Selector引用的是一个放在GDT或当前LDT中的可执行代码段。Offset域引用的是其ISR的入口地址。</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=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"></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=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"><IMG src="interrupt-handling_4.files/isr.gif" 
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/handling/isr.gif"></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1">当CPU调用一个ISR时,会将EFLAGS,CS,EIP寄存器压栈,其中CS,EIP寄存器的内容事实上是ISR的返回地址。如果一个Exception发生时,存在一个Error 
Code,那么这个Error Code会在EIP之后被压栈。</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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1">如果ISR和被打断的任务具有相同的特权等级,则CPU不改变Stack,让ISR继续使用当前的Stack。</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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"></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"><SPAN 
lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1">如果ISR的特权等级从数字上小于被打断任务的特权等级,也就是说如果ISR的权限大于被打断任务的权限,则会发生Stack 
Switch。为了能够在ISR结束之后,能够恢复使用原来的Stack,CPU会将SS和ESP寄存器的内容也压栈,并且这些内容都被压在新的Stack中,而不是Stack 
Switch之前的那个Stack。</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=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"><IMG src="interrupt-handling_4.files/intr_stack.gif" 
tppabs="http://pagoda-ooos.51.net/os_book/interrupt/handling/intr_stack.gif"></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=center><SPAN lang=EN-US><FONT face="Times New Roman TUR" size=3><SPAN 
style="mso-tab-count: 1"></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">问题是,CPU在Interrupt/Exception发生的时刻,发现特权等级不一致的时候,如何知道该使用那个栈?答案是通过当前任务的TSS。在TSS中存放着针对0,1,2三个特权等级的SS和ESP内容,当特权等级切换到某个特权等级的时候,CPU会从当前任务的TSS中找到相应特权等级的SS和ESP用来进行Stack 
Switch。</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">当ISR执行结束之后,需要继续执行之前被终止的任务,为了能够正确的做到这一点,ISR的返回必须使用IRET指令。</SPAN></FONT></SPAN></SPAN></FONT></SPAN><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">IRET指令会自动从Stack中恢复EFLAGS寄存器的值,并根据Stack中的CS,EIP内容挑转到被中断的位置。</SPAN></FONT></SPAN></SPAN></FONT></SPAN><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/Exception发生的时候,进行了Stack 
Switch,此时IRET会根据栈中的SS,ESP的内容将Stack切换回去。</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/Exception时,CPU会在将EFLAGS压栈之后,清除EFLAGS寄存器的TF flag。清除TF 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -