| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ; kernel.S - 中断处理程序
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- [bits 32]
- %define ERROR_CODE nop
- %define ZERO push 0
- extern put_str ; 声明外部函数
- extern idt_table ; idt_table 是 C 中注册的中断处理程序数组
- section .data
- intr_str db "interrup occur!", 0xa, 0
- global intr_entry_table
- intr_entry_table:
- %macro VECTOR 2
- section .text
- intr%1entry: ; 每个中断处理程序都要压入中断向量号,所以一个中断类型一个中断处理程序
- %2
- ; 保存上下文环境
- push ds
- push es
- push fs
- push gs
- pushad ; 保存通用寄存器的值, 依次是 eax, ecx, edx, ebx, esp, ebp, esi, edi
- ; 如果从片上进入的中断,除了从片上发送 EOI 外,还要往主片上发送 EOI
- mov al, 0x20 ; EOI 中断结束命令
- out 0xa0, al ; 发送给从片
- out 0x20, al ; 发送给主片
- push %1 ; 不管 idt_table 中的目标程序是否需要参数,都保存中断向量号,调试方便
- call [idt_table + %1 * 4] ; 调用中断处理程序(中断处理程序的地址存储在 idt_table 中,是 C 中注册的中断处理程序数组)
- jmp intr_exit ; 中断处理程序执行完毕,跳转到中断退出程序
- section .data
- dd intr%1entry ; 存储各个中断入口程序的地址,形成 intr_entry_table 数组
- %endmacro
- section .text
- global intr_exit
- intr_exit:
- add esp, 4 ; 跳过中断向量号
- popad ; 恢复通用寄存器的值
- pop gs
- pop fs
- pop es
- pop ds
- add esp, 4 ; 由于中断发生时,CPU 会自动压入错误码,所以在中断退出时,需要将错误码弹出
- iretd ; 从中断返回
- VECTOR 0x00, ZERO
- VECTOR 0x01, ZERO
- VECTOR 0x02, ZERO
- VECTOR 0x03, ZERO
- VECTOR 0x04, ZERO
- VECTOR 0x05, ZERO
- VECTOR 0x06, ZERO
- VECTOR 0x07, ZERO
- VECTOR 0x08, ZERO
- VECTOR 0x09, ZERO
- VECTOR 0x0a, ZERO
- VECTOR 0x0b, ZERO
- VECTOR 0x0c, ZERO
- VECTOR 0x0d, ZERO
- VECTOR 0x0e, ZERO
- VECTOR 0x0f, ZERO
- VECTOR 0x10, ZERO
- VECTOR 0x11, ZERO
- VECTOR 0x12, ZERO
- VECTOR 0x13, ZERO
- VECTOR 0x14, ZERO
- VECTOR 0x15, ZERO
- VECTOR 0x16, ZERO
- VECTOR 0x17, ZERO
- VECTOR 0x18, ZERO
- VECTOR 0x19, ZERO
- VECTOR 0x1a, ZERO
- VECTOR 0x1b, ZERO
- VECTOR 0x1c, ZERO
- VECTOR 0x1d, ZERO
- VECTOR 0x1e, ERROR_CODE
- VECTOR 0x1f, ZERO
- VECTOR 0x20, ZERO
|