中断和异常

什么是中断和异常?

我和小李正在聊天,小杨过来找我借钱。这种场景,我和小李的聊天被打断——中断!

我和小李在聊天,鸟屎拉在我头上。这种场景,我不得不停止与小李的聊天——出现异常!

当中断和异常的情况发生之后,我需要有处理这些突发情况的能力,然后就会去处理中断(坚决不借钱给朋友,我昨天才买了股票啊,确实不好意思啊),处理异常(呵呵,去洗澡)!

在现实世界中,我有很多中断、异常处理的能力,也有一些我没有的能力(41楼,断电时刻,地震来了)

异常类型

在计算机世界中,CPU也有一些中断和异常处理的能力:如下图

image

在CPU执行指令的过程中,如果遇到列表中的中断,CPU有能力自己去处理这些中断和异常,同时为了扩展CPU的异常处理能力,程序员还可以使用向量号在32~255之间的向量去自定义异常

类型:

Fault:是一个可以被操作系统修正的异常类型,当Fault发生,CPU就跳转到该Fault的中断处理程序,一旦程序处理完毕,CPU就会重新执行引起Fault发生的这条指令。比如:当程序员去访问一个物理内存时,如果内存里还没有数据,就会抛出14 #PF Fault,然后操作系统的Fault处理程序,就会将数据从其他存储介质加载到内存,然后操作系统返回,CPU继续执行  程序员访问物理内存的那条指令

Trap:   当CPU执行完一条Trap指令之后,就会立即触发Trasp,然后执行Trasp处理程序,处理完毕之后,Cpu会继续执行Traps指令之后的那一条命令。比如:INT 3就是一个Trap 指令,在程序调试期间,遇到断点,调试器就可以执行调试,当调试完毕之后,就可以继续执行程序指令的下一跳指令

Abort:  这种异常发生之后,CPU并不报告是哪条指令引发。这种异常发生过后程序通常找不到错误原因,所以不能去修正。比如:在服务器端发生的 硬盘错误,非法值读取,系统总线出错等!

中断类型

CPU具有处理中断的能力,那中断是如何产生的呢?

中断分为两种

软中断:就是上表定义的各种中断,还有用户自定义的各种中断!当系统调用 int 19就产生了软中断

硬中断:CPU在执行指令期间,计算机的其他硬件比如内存,硬盘等发出的中断。比如:

  • 系统时钟通过一个计数器(多基于某种振动频率)定期向CPU发出中断,CPU通过专门的时钟中断处理程序来保持计时。现代操作系统对系统时钟的另一个主要应用是为进程切换提供时机。一旦时钟中断发生,程序计数器会被自动压栈,而此时操作系统就有机会将程序状态及内存映像转存至别处,并调用进程调度程序来选择下一个进程,并将其进程状态,包括程序计数器,导入寄存器。这样下一个程序就可以运行。应注意进程调度程序的调度时机不止于时钟中断。
  • 磁盘中断标识某个磁盘设备完成了数据的发送/接收。磁盘中断发生后,等待这个中断的进程可以(但未必,这取决于进程调度程序当时的判断)继续执行。
  • 断电中断指示计算机能源即将丧失,计算机可以相应中断程序作有序的关机处理。

硬中断又分为两种:

  • 不可屏蔽 :中断发生之后,CPU必须处理中断
  • 可屏蔽:中断发生后,由于屏蔽了中断,CPU就当作没有发生中断

如何屏蔽中断

在CPU中有两个用来控制中断的控制器:可编程中断控制器8259A。

在初始化系统之前应该先将这两个控制器初始化,以确保中断处理正确。初始化必须遵守控制器的使用规则,过程如下:

; Init8259A ----------------------------
Init8259A:
    mov    al, 011h
    out    020h, al    ; 主8259, ICW1.
    call    io_delay

    out    0A0h, al    ; 从8259, ICW1.
    call    io_delay

    mov    al, 020h    ; IRQ0 对应中断向量 0x20
    out    021h, al    ; 主8259, ICW2.
    call    io_delay

    mov    al, 028h    ; IRQ8 对应中断向量 0x28
    out    0A1h, al    ; 从8259, ICW2.
    call    io_delay

    mov    al, 004h    ; IR2 对应从8259
    out    021h, al    ; 主8259, ICW3.
    call    io_delay

    mov    al, 002h    ; 对应主8259的 IR2
    out    0A1h, al    ; 从8259, ICW3.
    call    io_delay

    mov    al, 001h
    out    021h, al    ; 主8259, ICW4.
    call    io_delay

    out    0A1h, al    ; 从8259, ICW4.
    call    io_delay

    mov    al, 11111110b    ; 仅仅开启定时器中断
    ;mov    al, 11111111b    ; 屏蔽主8259所有中断
    out    021h, al    ; 主8259, OCW1.
    call    io_delay

    mov    al, 11111111b    ; 屏蔽从8259所有中断
    out    0A1h, al    ; 从8259, OCW1.
    call    io_delay

    ret
; Init8259A --------------------------- 

io_delay:
    nop
    nop
    nop
    nop
    ret

 http://blog.csdn.net/begginghard/article/details/7284834

posted @ 2014-04-01 09:40  Pavkoo  阅读(557)  评论(0编辑  收藏  举报