美文网首页
中断机制

中断机制

作者: August_0d36 | 来源:发表于2018-03-23 20:56 被阅读0次

     中断机制是现代计算机系统中的基本机制之一,他完成了对计算机各个事件(如时钟、键盘等)响应工作。
     首先,中断分为 软中断硬件中断。其中软中断又被称为 异常(exception),他用于处理计算机执行过程中的一些异常情况,如除0操作、溢出、栈错误等情况,这些中断 不可屏蔽。而硬件中断又分为了外部中断(可屏蔽)内部中断(不可屏蔽),外部中断一般就是计算机外设所发出的中断(如敲击了键盘等),它们由如下图所示的两个级联的8259A芯片所控制 ;内部中断就是计算机内部硬件出现的像硬件出错(掉电、校验、传输)等情况所发出的中断。上述所有的这些中断,都被统一的编排在了接下来将介绍的中断向量表中。


     8086机器中的中断向量表在80386机器中被改为了中断描述符表(interrupt description table,IDT),它存放着用于描述各个中断的表项,每个都由8字节组成,包括了该中断的地址、特权级等信息。这些表项又被称为了门描述符(Gate Descriptor),“门”的含义是当中断发生时必须先通过这些门,然后才能进入相应的中断处理程序(Interrupt Service Routine, ISR)

     如前文所述,所有的中断(或异常)都被统一的编排在了IDT中,即这个IDT包含了异常向量和硬件中断向量,而IDT中一共有256个门描述符,每个门描述符描述一个中断(或异常),同时就对应着一个中断(或异常)的处理程序。这256个中断或异常向量的分配如下:
    • 从0~31 的向量对应于异常和非屏蔽中断;
    • 从32~47 的向量(即由I/O 设备引起的中断)分配给屏蔽中断;
    • 剩余的从48~255 的向量用来标识软中断。Linux 只用了其中的一个(即128 或0x80向量)用来实现系统调用(trap)。当用户态下的进程执行一条int 0x80 汇编指令时,CPU 就切换到内核态,并开始执行system_call() 内核函数。

     我们先说异常的处理。在这256个处理程序中,前32个都是非屏蔽中断,0~20号中断处理程序又都用于CPU的异常中断(即软中断),随后的12个中断处理程序被Intel保留,详细情况如下:

    // 0~31个都是非屏蔽中断
    // 声明中断处理函数 0-19 属于 CPU 的异常中断 
    // ISR:中断处理程序(interrupt service routine)
    void isr0();        // 0 #DE 除 0 异常 
    void isr1();        // 1 #DB 调试异常 
    void isr2();        // 2 NMI 
    void isr3();        // 3 BP 断点异常 
    void isr4();        // 4 #OF 溢出 
    void isr5();        // 5 #BR 对数组的引用超出边界 
    void isr6();        // 6 #UD 无效或未定义的操作码 
    void isr7();        // 7 #NM 设备不可用(无数学协处理器) 
    void isr8();        // 8 #DF 双重故障(有错误代码) 
    void isr9();        // 9 协处理器跨段操作 
    void isr10();       // 10 #TS 无效TSS(有错误代码) 
    void isr11();       // 11 #NP 段不存在(有错误代码) 
    void isr12();       // 12 #SS 栈错误(有错误代码) 
    void isr13();       // 13 #GP 常规保护(有错误代码) 
    void isr14();       // 14 #PF 页故障(有错误代码) 
    void isr15();       // 15 CPU 保留 
    void isr16();       // 16 #MF 浮点处理单元错误 
    void isr17();       // 17 #AC 对齐检查 
    void isr18();       // 18 #MC 机器检查 
    void isr19();       // 19 #XM SIMD(单指令多数据)浮点异常
    // 20-31 Intel 保留
    //...
    

     其次再说硬件中断的处理。在前面的8259A芯片的示意图中,可能你已经发现,我们给每一个外部中断(可屏蔽中断)都赋予了一个编号,这16个编号被称作中断请求号码(Interrupt Request, IRQ)。它们实际上就是IDT中的32~47号向量,详细情况如下:

    // IRQ 定义
    // 定义IRQ
    #define  IRQ0     32    // 电脑系统计时器
    #define  IRQ1     33    // 键盘
    #define  IRQ2     34    // 与 IRQ9 相接,MPU-401 MD 使用
    #define  IRQ3     35    // 串口设备
    #define  IRQ4     36    // 串口设备
    #define  IRQ5     37    // 建议声卡使用
    #define  IRQ6     38    // 软驱传输控制使用
    #define  IRQ7     39    // 打印机传输控制使用
    #define  IRQ8     40    // 即时时钟
    #define  IRQ9     41    // 与 IRQ2 相接,可设定给其他硬件
    #define  IRQ10    42    // 建议网卡使用
    #define  IRQ11    43    // 建议 AGP 显卡使用
    #define  IRQ12    44    // 接 PS/2 鼠标,也可设定给其他硬件
    #define  IRQ13    45    // 协处理器使用
    #define  IRQ14    46    // IDE0 传输控制使用
    #define  IRQ15    47    // IDE1 传输控制使用
    
    // 外部中断 
    // 声明 IRQ 函数
    // IRQ:中断请求(Interrupt Request)
    void irq0();        // 电脑系统计时器
    void irq1();        // 键盘
    void irq2();        // 与 IRQ9 相接,MPU-401 MD 使用
    void irq3();        // 串口设备
    void irq4();        // 串口设备
    void irq5();        // 建议声卡使用
    void irq6();        // 软驱传输控制使用
    void irq7();        // 打印机传输控制使用
    void irq8();        // 即时时钟
    void irq9();        // 与 IRQ2 相接,可设定给其他硬件
    void irq10();       // 建议网卡使用
    void irq11();       // 建议 AGP 显卡使用
    void irq12();       // 接 PS/2 鼠标,也可设定给其他硬件
    void irq13();       // 协处理器使用
    void irq14();       // IDE0 传输控制使用
    void irq15();       // IDE1 传输控制使用
    

     用户程序可通过INT指令加一个中断向量(0~255)像系统发出一个中断请求。

    相关文章

      网友评论

          本文标题:中断机制

          本文链接:https://www.haomeiwen.com/subject/epaxcftx.html