中断、异常、trap 的区别

【1】无论是中断,还是异常和陷阱,对应的处理函数,一般都可以称其为中断服务程序ISR,

           都只是一个函数 具体函数里面要做什么事情,是由你写程序的人决定的。 

【2】 比如中断中处理对应的事情,异常中自己决定如何响应出现的异常,陷阱中决定做什么事情。



【3】    中断:是为了设备与CPU之间的通信。典型的有如服务请求,任务完成提醒等。比如我们熟知的时钟中断,硬盘读写服务请求中断。中断的发生与系统处在用户态还是在内核态无关,只决定于EFLAGS寄存器的一个标志位。我们熟悉的sti, cli两条指令就是用来设置这个标志位,然后决定是否允许中断。在单个CPU的系统中,这也是保护临界区的一种简便方法。中断是异步的,因为从逻辑上来说,中断的产生与当前正在执行的进程无关。事实上,中断是如此有用,Linux用它来统计时钟,进行硬盘读写等。
【4】   异常:异常是由当前正在执行的进程产生。异常包括很多方面,有出错(fault),有陷入(trap),也有可编程异常(programmable exception)。出错(fault)和陷入(trap)最重要的一点区别是他们发生时所保存的EIP值的不同。出错(fault)保存的EIP指向触发异常的那条指令;而陷入(trap)保存的EIP指向触发异常的那条指令的下一条指令。因此,当从异常返回时,出错(fault)会重新执行那条指令;而陷入(trap)就不会重新执行。这一点实际上也是相当重要的,比如我们熟悉的缺页异常(page fault),由于是fault,所以当缺页异常处理完成之后,还会去尝试重新执行那条触发异常的指令(那时多半情况是不再缺页)。陷入的最主要的应用是在调试中,被调试的进程遇到你设置的断点,会停下来等待你的处理,等到你让其重新执行了,它当然不会再去执行已经执行过的断点指令。
【5】   可编程中断:这类中断可由编程者用int指令来触发。在Linux中,使用了一个,也是唯一的一个可编程中断,就是int 0x80系统调用。硬件对可编程中断的处理与对trap的处理类似,即从这类异常返回时也是返回到触发异常的下一条指令。关于可编程中断,还有另外一种说法:软件中断(software interrupt),其实是一个意思。


8086/8088把中断分为内部中断和外部中断两大类。为了支持多任务和虚拟存储器等功能,80386把外部中断称为“中断”,把内部中断称为“异常”。与8086/8088一样,80386通常在两条指令之间响应中断或异常。80386最多处理256种中断或异常。     
  1.中断   
          对80386而言,中断是由异步的外部事件引起的。外部事件及中断响应与正执行的指令没有关系。通常,中断用于指示I/O设备的一次操作已完成。与8086/8088一样,80386有两根引脚INTR和NMI接受外部中断请求 信号 。INTR接受可屏蔽中断请求。NMI接受不可屏蔽中断请求。在80386中,标志寄存器EFLAGS中的IF标志决定是否屏蔽可屏蔽中断请求。     


4.6.7 中断描述符表

      中断描述符表(Interrupt Descriptor Table,IDT)将每个异常或中断向量分别与它们的处理过程联系起来。与GDT和LDT表类似,IDT也是由8字节长描述符组成的一个数组。与GDT 不同的是,表中第1项可以包含描述符。为了构成IDT表中的一个索引值,处理器把异常或中断的向量号乘以8。因为最多只有256个中断或异常向量,所以 IDT无需包含多于256个描述符。IDT中可以含有少于256个描述符,因为只有可能发生的异常或中断才需要描述符。不过IDT中所有空描述符项应该设置其存在位(标志)为0。

IDT表可以驻留在线性地址空间的任何地方,处理器使用IDTR寄存器来定位IDT表的位置。这个寄存器中含有IDT表32位的基地址和16位的长度(限长)值,如图4-26所示。IDT表基地址应该对齐在8字节边界上以提高处理器的访问效率。限长值是以字节为单位的IDT表的长度。

                                                                 
                                                                             图4-26 中断描述符表IDT和寄存器IDTR

      LIDT和SIDT指令分别用于加载和保存IDTR寄存器的内容。LIDT指令用于把内存中的限长值和基地址操作数加载到IDTR寄存器中。该指令仅能由当前特权级CPL是0的代码执行,通常被用于创建IDT时的操作系统初始化代码中。SIDT指令用于把IDTR中的基地址和限长内容复制到内存中。该指令可在任何特权级上执行。

如果中断或异常向量引用的描述符超过了IDT的界限,处理器会产生一个一般保护性异常。

4.6.8 IDT描述符

        IDT表中可以存放3种类型的门描述符:中断门(Interrupt gate)描述符、陷阱门(Trap gate)描述符、任务门(Task gate)描述符。

图4-27给出了这三种门描述符的格式。中断门和陷阱门含有一个长指针(即段选择符和偏移值),处理器使用这个长指针把程序执行权转移到代码段中异常或中断的处理过程中。这两个段的主要区别在于处理器操作EFLAGS寄存器IF标志上。IDT中任务门描述符的格式与GDT和LDT中任务门的格式相同。任务门描述符中含有一个任务TSS段的选择符,该任务用于处理异常或中断。

                                                  
 图4-27 中断门、陷阱门和任务门描述符格式


4.6.9 异常与中断处理

       处理器对异常和中断处理过程的调用操作方法与使用CALL指令调用程序过程和任务的方法类似。当响应一个异常或中断时,处理器使用异常或中断的向量作为IDT表中的索引。如果索引值指向中断门或陷阱门,则处理器使用与CALL指令操作调用门类似的方法调用异常或中断处理过程。如果索引值指向任务门,则处理器使用与CALL指令操作任务门类似的方法进行任务切换,执行异常或中断的处理任务。

异常或中断门引用运行在当前任务上下文中的异常或中断处理过程,如图4-28所示。门中的段选择符指向GDT或当前LDT中的可执行代码段描述符。门描述符中的偏移字段指向异常或中断处理过程的开始处。

                                                   
                                                                                      图4-28 中断过程调用

当处理器执行异常或中断处理过程调用时会进行以下操作:

(1)如果处理过程将在高特权级(如0级)上执行时就会发生堆栈切换操作。堆栈切换过程如下:

       处理器从当前执行任务的TSS段中得到中断或异常处理过程使用的堆栈的段选择符和栈指针(例如tss.ss0、tss.esp0)。然后处理器会把被中断程序(或任务)的栈选择符和栈指针压入新栈中,如图4-29所示。

                                                          
                                                            图4-29 转移到中断处理过程时堆栈的使用方法

      接着处理器会把EFLAGS、CS和EIP寄存器的当前值也压入新栈中。如果异常会产生一个错误号,那么该错误号也会被最后压入新栈中。

(2)如果处理过程将在被中断任务同一个特权级上运行,那么:

      处理器把EFLAGS、CS和EIP寄存器的当前值保存在当前堆栈上。如果异常会产生一个错误号,那么该错误号也会被最后压入新栈中。

为了从中断处理过程中返回,处理过程必须使用IRET指令。IRET指令与RET指令类似,但IRET还会把保存的寄存器内容恢复到EFLAGS 中。不过只有当CPL是0时才会恢复EFLAGS中的IOPL字段,并且只有当CPL不大于IOPL时,IF标志才会被改变。 如果当调用中断处理过程时发生了堆栈切换,那么在返回时IRET指令会切换到原来的堆栈。

(1)异常和中断处理过程的保护

       异常和中断处理过程的特权级保护机制与通过调用门调用普通过程类似。处理器不允许把控制转移到比CPL更低特权级代码段的中断处理过程中,否则将产生一个一般保护性异常。另外,中断和异常的保护机制在以下方面与一般调用门过程不同:

因为中断和异常向量没有RPL,因此在隐式调用异常和中断处理过程时不会检查RPL。

只有当一个异常或中断是由INT n、INT 3或INT 0指令产生时,处理器才会检查中断或陷阱门中的DPL。此时CPL必须小于或等于门的DPL。这个限制可以防止运行在特权级3的应用程序使用软件中断访问重要的异常处理过程,例如页错误处理过程,假设这些处理过程已被存放在更高特权级的代码段中。对于硬件产生的中断和处理器检测到的异常,处理器会忽略中断门和陷阱门中的DPL。

因为异常和中断通常不会定期发生,因此这些有关特权级的规则有效地增强了异常和中断处理过程能够运行的特权级限制。我们可以利用以下技术之一来避免违反特权级保护:

异常或中断处理程序可以存放在一个一致性代码段中。这个技术可以用于只需访问堆栈上数据的处理过程(如除出错异常)。如果处理程序需要数据段中的数据,那么特权级3必须能够访问这个数据段。但这样一来就没有保护可言了。

处理过程可以放在具有特权级0的非一致代码段中。这种处理过程总是可以执行的,与被中断程序或任务的当前特权级CPL无关。

(2)异常或中断处理过程的标志使用方式

        当通过中断门或陷阱门访问一个异常或中断处理过程时,处理器会在把EFLAGS寄存器内容保存到堆栈上之后清除EFLAGS中的TF标志。清除TF标志可以防止指令跟踪影响中断响应。而随后的IRET指令会用堆栈上的内容恢复EFLAGS的原TF标志。

中断门与陷阱门唯一的区别在于处理器操作EFLAGS寄存器IF标志的方法。当通过中断门访问一个异常或中断处理过程时,处理器会复位IF标志以防止其他中断干扰当前中断处理过程。随后的IRET指令则会用保存在堆栈上的内容恢复EFLAGS寄存器的IF标志。而通过陷阱门访问处理过程并不会影响 IF标志。

(3)执行中断处理过程的任务

        当通过IDT表中任务门访问异常或中断处理过程时,就会导致任务切换。从而可以在一个专用任务中执行中断或异常处理过程。IDT表中的任务门引用 GDT中的TSS描述符。切换到处理过程任务的方法与普通任务切换一样。由于本书讨论的Linux操作系统没有使用这种中断处理方式,因此这里不再赘述。

4.6.10 中断处理任务

       当通过IDT中任务门来访问异常或中断处理过程时就会导致任务切换。使用单独的任务来处理异常或中断有如下好处:

被中断程序或任务的完整上下文会被自动保存。

在处理异常或中断时,新的TSS可以允许处理过程使用新特权级0的堆栈。在当前特权级0的堆栈已毁坏时如果发生了一个异常或中断,那么在为中断过程提供一个新特权级0的堆栈条件下,通过任务门访问中断处理过程能够防止系统崩溃。

通过使用单独的LDT给中断或异常处理任务独立的地址空间,可以把它与其他任务隔离开来。

使用独立任务处理异常或中断的不足之处是:在任务切换时必须对大量机器状态进行保存,使得它比使用中断门的响应速度要慢,导致中断延时增加。

IDT中的任务门会引用GDT中的TSS描述符,如图4-30所示。切换到句柄任务的过程与普通任务切换过程相同。到被中断任务的反向链接会被保存在句柄任务TSS的前一任务链接字段中。如果一个异常会产生一个出错码,则该出错码会被复制到新任务堆栈上。

                                                
                                                                               图4-30 中断处理任务切换

当异常或中断句柄任务用于操作系统中时,实际上有两种分派调度任务的机制:操作系统软件调度和处理器中断机制的硬件调度。使用软件调度方法时需要考虑到中断开启时采用中断处理任务。


  1. 中断信号的作用.
    1. 使CPU转而去运行正常控制流之外的代码.为了它.就要在内核态堆栈保存程序计数器的当前值(eip和cs寄存器).并把与中断类型相关的一个地址放在程序计数器.
    2. 中断处理与进程切换的差异:由中断或异常处理程序执行的代码不是一个进程,而是内核控制路径.代表中断发生时正在运行的进程执行.其比进程"轻".
  2. 中断和异常
    1. 中断:
      1. 可屏蔽中断(maskable): I/O设备发出的中断请求(irq)都属于.可处于两种状态:屏蔽的/非屏蔽的.
      2. 非屏蔽中断(nonmaskable): 只有几个危急事件才引起.总是由CPU辨认.
    2. 异常:
      1. 处理器探测异常:当CPU执行指令时探测到一个反常条件所产生的异常. 根据保存在eip寄存器中的值,分为3种; 1)故障(fault):通常可以被纠正.eip中保存的是引起故障的指令地址.纠正后会重新执行该条指令. ; 2)陷阱(trap):在陷阱指令执行后立刻报告.内核把控制器返回给程序后可以继续他的执行而不失连贯性. eip保存的是随后要执行的指令地址.只有当没有必要重新执行已终止的指令时(通常为了调试程序)时才触发陷阱. ; 3)异常中止(abort):不能在eip中保存引起异常的指令所在的确切位置.用于报告严重的错误.异常中止处理程序会强制受影响的进程终止.
      2. 编程异常: 在编程者发出请求时发生.将其作为陷阱来处理.也叫软中断.用途:1)执行系统调用.2)给调试程序通报一个特定的事件.
    3. 每个中断和异常由0~255之间的一个数来标示.称为向量(vector).只有可屏蔽中断的向量可以通过编程改变.其余都是固定的.  
    4. IRQ和中断:能发出中断的设备都有一个IRQ的输出线.所有IRQ线都与一个可编程中断控制器(PIC)的硬件电路的输入引脚相连.可以有选择地禁止每条IRQ线.可对PIC编程从而禁止IRQ.禁止的中断不丢失.一旦激活,PIC就把他们发送到CPU.该特性运行中断处理程序逐次处理同一类型的IRQ.
    5. 为了发挥SMP体系的并行性,能够把中断传递给每个CPU很重要.所以引入了I/O高级可编程控制器(I/O APIC)的组件.所有CPU都含有一个本地APIC,通过APIC总线(在系统总线上)连接到外部的I/O APIC.还支持CPU产生处理器间中断(IPI),可以利用它来在CPU之间交换消息.
    6. 中断描述符表:IDT是一个系统表,它与每一个中断或异常向量相联系.每一个向量在表中有相应的中断或异常处理程序的入口地址.最多需要256*8=2048字节来存放IDT. idtr寄存器指定IDT的线性基地址及其最大长度,从而使IDT可以位于内存中的任何地方.分为3种类型: 1)任务门:信号发生时,必须取代当前进程的那个进程的TSS选择符存放在任务门中. ;2)中断门:包含段选择符和处理程序的段内偏移量.当CPU控制权转移到一个适当的断后,清除IF标志来关闭将来会发生的可屏蔽中断 ;3)陷阱门:与中断门相似,但控制权传递到一个适合的CPU时不修改IF标志.  Linux利用中断门处理中断,利用陷阱门处理异常.注意: "Double fault"异常是唯一由任务们处理的异常.表示一种内核错误.
  3. 中断和异常处理程序的嵌套执行.
    1. 必须保证中断处理程序永不阻塞,即中断处理程序运行期间不能发生进程切换.因为嵌套的内核控制路径恢复执行时需要的数据都存放在当前线程的内核态堆栈上.
    2. 一个中断处理程序可以抢占其他的中断处理程序和异常处理程序.异常处理程序从不抢占中断处理程序.
  4. 初始化中断描述符表
    1. 过程: 1)在初始化系统时把IDT表的初始地址装入idtr寄存器,并初始化表中的每一项.; 2)int指令用于在用户态进程发出一个中断信号,为了防止模拟非法的中断,将门描述符的DPL=0.; 3)在用户态进程必须要能够发出一个编程异常时,将门的SPL=3。
    2. Linux中的分类: 中断门(DPL=0,所有LInux中断处理程序都通过中断门激活,并限制在内核态); 系统门(DPL=3,用来激活3个linux异常处理程序); 系统中断门(DPL=3,激活int3的异常处理程序); 陷阱门(DPL=0,激活大部分的异常处理程序); 任务门(DPL=0,"Double Fault的异常处理).
    3. idt的初始化分为两步:1)将256个表项用同一个中断门(即指向ignore_int()中断处理程序:其是一个空的处理程序)来填充.2)用有意义的陷阱和中断处理程序来代替空处理程序.
  5. 异常处理
    1. 大部分异常都解释成为出错条件.当异常发生时,内核向引起异常的进程发送一个信号向它通知一个反常条件.
    2. 特殊情况: 1)"Device not availeble" 2)"Page Fault"该异常推迟给进程分配新的页框,直到不能再推迟位置.
    3. 异常处理程序的标准结构: 1)在内核态堆栈中保存大多数寄存器的内容; 2)用C函数处理异常; 3)通过ret_from_exception函数从异常处理程序退出.
  6. 中断处理
    1. 由于一个进程被挂起好久后中断才到达,因此一个完全无关的进程可能正在运行.所以发送信号给当前进程是无用的.
    2. 中断处理依赖于中断类型:1)I/O中断(查询设备以确定适当的操作过程); 2)时钟中断(该中断告诉内核一个固定的时间间隔已经过去,作为I/O中断处理) ;3)处理器间中断.
    3. I/O中断处理:要能给多个设备同时提供服务.实现: 1)IRQ共享(每个ISR(中断服务例程)是一个与单独设备(共享IRQ线)相关的函数,因为无法预知那个特定的设备产生IRQ,所以,中断处理程序执行多个ISR,以验证它的设备是否需要关注,如果是,当设备产生中断时就执行所需的操作); 2)IRQ动态分配(一条IRQ线在可能的最后时刻才与一个设备相关联.这样,即使几个设备并不共享IRQ线,但同一IRQ向量也可以由这几个设备在不同时刻使用).
      1. 一个中断处理程序正在执行时,相应的IRQ线上发出的信号被暂时忽略; 中断处理程序所代表的进程必须是出于Task_Running态的; 其不能执行任何阻塞过程.
      2. 中断要执行的操作: 1)紧急的(在禁止可屏蔽中断下立即执行); 2)非紧急的(在开中断下立即执行); 3)非紧急可延迟的(由独立的函数执行).
      3. 步骤:1)在内核态堆栈中保存IRQ的值和寄存器的内容; 2)为正在给IRQ线服务的PIC发送一个应答来允许PIC进一步发出中断; 3)执行共享这个IRQ的所有设备的ISR; 4)跳到ret_from_intr()的地址后终止.
      4. IRQ数据结构: 1)意外中断:中断内核没有处理的中断.原因是与某个IRQ线相关的ISR不存在或者与某个中断线相关的所有例程都识别不出来.当一条IRQ线上的意外中断次数过多时,就禁用这条IRQ线. 2)
      5. IRQ在多CPU系统上的分发:对称多处理器模型(SMP).一般情况下,内核能够公平地在CPU间分发中断.但是在某些情况下,Linxu需要使用kirqd的内核线程来纠正IRQ的自动分配.其利用了CPU的IRQ亲和力:通过修改I/O APIC的中断重定向表表项,可以吧中断信号发送到某个特定的CPU上.
    4. CPU间中断处理:IPI不通过IRQ线传输,而是作为信号直接放在连接所有CPU本地APIC总线上. 类型: 1)Call_Function_Vector(发往不包含发送者的所有CPU,强制这些CPU运行发送者传递过来的函数). 2)Reschedule_Vector(从中断返回后,所有的重新调度都自动运行); 3)Invalidate_TLB_Vector(强制TLB无效,来刷新CPU的TLB).
  7. 软中断及tasklet:
    1. 可延迟中断可以在开中断的情况下执行.把可延迟中断从中断处理程序中抽出来有助于使内核保持较短的响应时间.Linux通过两种非紧迫,可中断内核函数:1)可延迟函数;2)通过工作队列来执行的函数.
    2. tasklet是在软中断之上实现的.软中断的分配是静态的,tasklet的分配和初始化是在运行时.软中断是可重入函数并使用自旋锁来保护数据,其实可以并行在多CPU上执行的,tasklet总是串行执行,但是不同类型的tasklet可以并发执行,其不必是可重入的.四种操作:1)初始化;2)激活;3)屏蔽;4)执行.激活和执行被绑定在一个CPU上,虽然可以更好地利用CPU的Cache,但是有潜在的危险性(一个CPU很忙,但其他的很闲).
    3. 软中断:使用下标(共6个)来表示优先级.softirq_action[32]  softirq_vec数组.优先级是下标,所以只有前6元素个有效.另外,thread_info中有一个preempt_count字段来跟踪内核抢占和内核控制路径的嵌套.
    4. 每个CPu都有自己的ksoftirqd/n内核线程.其为了解决以下问题:软中断函数可以重新激活自己,软中断的连续高流量可能会产生问题.不然就要选择以下两种之一的策略:1)忽略do_softirq()运行时新出现的软中断,此种情况的等待是不可接受的;2)不断地重新检查挂起的软中断,这种情况下,do_softirq()函数就会一直不返回,用户态程序实际上停止执行.解决:do_softirq()函数确定哪些软中断是挂起的,并执行他们的韩素华.如果已经执行的软中断又被激活,则do_softirq()唤醒内核线程并终止.内核线程有较低的优先级,因此用户程序有就会运行.但是,如果机器空闲(没有用户态程序需要运行时),挂起的软中断就很快被执行.
    5. tasklet:是I/O驱动程序中实现可延迟函数的首选.
  8. 工作队列
    1. 用来代替任务队列.允许内核函数被激活,而且稍后由一种叫做工作者线程的特殊内核线程来执行.
    2. 可延迟函数运行在中断上下文中,而工作队列中的函数运行在进程上下文中.执行可阻塞函数的方式是在进程上下文中运行,因为在中断上下文中不可能发生进程切换.两者都不能访问进程的用户态地址空间.

          外部硬件在通过INTR发出中断请求信号的同时,还要向处理器给出一个8位的中断向量。处理器在响应可屏蔽中断请求时,读取这个由外部硬件给出的中断向量号。处理器对这个中断向量号并没有规定。但在具体的微机系统中,系统必须通过软件和硬件的配合设置,使得给出的这个中断向量号不仅与外部中断源对应,而且要避免中断向量号使用冲突情况的出现。可 编程 中断控制器芯片8259A可配合80386工作,能够根据设置向处理器提供上述中断向量号,还能处理中断请求的优先级。每个8259A芯片可以支持8路中断请求信号,如果使用9个8259A芯片(一个主片,8个从片),就可使80386在单个引脚INTR上接受多达64个中断源的中断请求信号。     
          处理器不屏蔽来自NMI的中断请求。处理器在响应NMI中断时,不从外部硬件接收中断向量号。与8086/8088一样,在80386中,不可屏蔽中断所对应的中断向量号固定为2。为了不可屏蔽中断的嵌套,每当接受一个NMI中断,处理器就在内部屏蔽了再次响应NMI,这一屏蔽过程直到执行中断返回指令IRET后才结束。所以,NMI处理程序应以IRET指令结束。     
  2.异常   
          异常是80386在执行指令期间检测到不正常的或非法的条件所引起的。异常与正执行的指令有直接的 联系 。例如,执行除法指令时,除数等于0。再如,执行指令时发现特权级不正确。当发生这些情况时,指令就不能成功完成。软中断指令“INT   n”和“INTO”也归类于异常而不称为中断,这是因为执行这些指令产生异常事件。     
          80386识别多种不同类别的异常,并赋予每一种类别以不同的中断向量号。异常发生后,处理器就象响应中断那样处理异常。即根据中断向量号,转相应的中断处理程序。把这种中断处理程序称为异常处理程序可能更合适。     
          根据引起异常的程序是否可被恢复和恢复点不同,把异常进一步分类为故障(Fault)、陷阱(Trap)和中止(Abort)。我们把对应的异常处理程序分别称为故障处理程序、陷阱处理程序和中止处理程序。     
          故障是在引起异常的指令之前,把异常情况通知给系统的一种异常。80386认为故障是可排除的。当控制转移到故障处理程序时,所保存的断点CS及EIP的值指向引起故障的指令。这样,在故障处理程序把故障排除后,执行IRET返回到引起故障的程序继续执行时,刚才引起故障的指令可重新得到执行。这种重新执行,不需要操作系统软件的额外参与。故障的发现可能在指令开始执行之前,也可能在指令执行期间。如果在指令执行期间检测到故障,那么中止故障指令,并把指令的操作数恢复为指令开始执行之前的值。这可保证故障指令的重新执行得到正确的结果。例如,在一条指令的执行期间,如果发现段不存在,那么停止该指令的执行,并通知系统产生段故障,对应的段故障处理程序可通过加载该段的方法来排除故障,之后,原指令就可成功执行,至少不再发生段不存在的故障。     
          陷阱是在引起异常的指令之后,把异常情况通知给系统的一种异常。当控制转移到异常处理程序时,所保存的断点CS及EIP的值指向引起陷阱的指令的下一条要执行的指令。下一条要执行的指令,不一定就是下一条指令。因此,陷阱处理程序并不是总能根据保存的断点,反推确定出产生异常的指令。在转入陷阱处理程序时,引起陷阱的指令应正常完成,它有可能改变了寄存器或存储单元。软中断指令、单步异常是陷阱的例子。     
          中止是在系统出现严重情况时,通知系统的一种异常。引起中止的指令是无法确定的。产生中止时,正执行的程序不能被恢复执行。系统接收中止后,处理程序要重新建立各种系统表格,并可能重新启动操作系统。硬件故障和系统表中出现非法值或不一致的值是中止的例子。   
软硬中断问题
    要搞清楚什么是软中断,什么是硬中断,就必须了解软件中断存在的机理.
    现代的单片机应用中,往往伴随着操作系统的应用,单片机为了方便操作系统编程,会保留一些特权指令,方便操作系统控制整个机器,也为了方便软件中的一些原子操作,这些原子操作不允许中断破坏,软中断指令表面上类似于函数调用,与函数调用相比,更重要的功能是使单片机进入特权运行状态,在这个状态下,操作系统可以做一些用户状态下不能使用的功能.
    像51这类没有特权功能的单片机是不存在也没有必要存在软件中断功能的.
    区别软硬件中断的方法很简单,CPU的手册会告诉你哪条指令会产生软件中断.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值