[section .text] ; 导入 extern StackTop ; kern/astart.asm extern tss ; inc/protect.h extern k_reenter ; inc/trap.h extern exception_handler ; inc/trap.h extern irq_table ; inc/trap.h extern p_proc_ready ; inc/process.h ; 具体看inc/process.h pcb维护的寄存器表 P_STACKBASE equ 0 GSREG equ P_STACKBASE FSREG equ GSREG + 4 ESREG equ FSREG + 4 DSREG equ ESREG + 4 EDIREG equ DSREG + 4 ESIREG equ EDIREG + 4 EBPREG equ ESIREG + 4 KERNELESPREG equ EBPREG + 4 EBXREG equ KERNELESPREG + 4 EDXREG equ EBXREG + 4 ECXREG equ EDXREG + 4 EAXREG equ ECXREG + 4 RETADR equ EAXREG + 4 EIPREG equ RETADR + 4 CSREG equ EIPREG + 4 EFLAGSREG equ CSREG + 4 ESPREG equ EFLAGSREG + 4 SSREG equ ESPREG + 4 P_STACKTOP equ SSREG + 4 save: pushad ; `. push ds ; | push es ; | 保存原寄存器值 push fs ; | push gs ; / mov dx, ss mov ds, dx mov es, dx mov eax, esp ;eax = 进程表起始地址 inc dword [k_reenter] ;k_reenter++; cmp dword [k_reenter], 0 ;if(k_reenter ==0) jne .1 ;{ mov esp, StackTop ; mov esp, StackTop <--切换到内核栈 push restart ; push restart jmp [eax + RETADR - P_STACKBASE]; return; .1: ;} else { 已经在内核栈,不需要再切换 push restart_reenter ; push restart_reenter jmp [eax + RETADR - P_STACKBASE]; return; ;} ; 具体看inc/protect.h TSS维护的寄存器表 TSS3_S_SP0 equ 4 restart: mov esp, [p_proc_ready] lea eax, [esp + P_STACKTOP] mov dword [tss + TSS3_S_SP0], eax restart_reenter: cli dec dword [k_reenter] pop gs pop fs pop es pop ds popad add esp, 4 iretd EOI equ 0x20 INT_M_CTL equ 0x20 ; I/O port for interrupt controller INT_M_CTLMASK equ 0x21 ; setting bits in this port disables ints INT_S_CTL equ 0xA0 ; I/O port for second interrupt controller INT_S_CTLMASK equ 0xA1 ; setting bits in this port disables ints ; 中断和异常 -- 硬件中断 ; --------------------------------- %macro hwint_master 1 call save in al, INT_M_CTLMASK ; `. or al, (1 << %1) ; | 屏蔽当前中断 out INT_M_CTLMASK, al ; / mov al, EOI ; `. 置EOI位 out INT_M_CTL, al ; / sti ; CPU在响应中断的过程中会自动关中断,这句之后就允许响应新的中断 push %1 ; `. call [irq_table + 4 * %1] ; | 中断处理程序 pop ecx ; / cli in al, INT_M_CTLMASK ; `. and al, ~(1 << %1) ; | 恢复接受当前中断 out INT_M_CTLMASK, al ; / ret %endmacro ALIGN 16 hwint00: ; Interrupt routine for irq 0 (the clock). hwint_master 0 ALIGN 16 hwint01: ; Interrupt routine for irq 1 (keyboard) hwint_master 1 ALIGN 16 hwint02: ; Interrupt routine for irq 2 (cascade!) hwint_master 2 ALIGN 16 hwint03: ; Interrupt routine for irq 3 (second serial) hwint_master 3 ALIGN 16 hwint04: ; Interrupt routine for irq 4 (first serial) hwint_master 4 ALIGN 16 hwint05: ; Interrupt routine for irq 5 (XT winchester) hwint_master 5 ALIGN 16 hwint06: ; Interrupt routine for irq 6 (floppy) hwint_master 6 ALIGN 16 hwint07: ; Interrupt routine for irq 7 (printer) hwint_master 7 ; --------------------------------- %macro hwint_slave 1 hlt ; 后面的8个外设中断暂时不需要,先hlt休眠核 %endmacro ; --------------------------------- ALIGN 16 hwint08: ; Interrupt routine for irq 8 (realtime clock). hwint_slave 8 ALIGN 16 hwint09: ; Interrupt routine for irq 9 (irq 2 redirected) hwint_slave 9 ALIGN 16 hwint10: ; Interrupt routine for irq 10 hwint_slave 10 ALIGN 16 hwint11: ; Interrupt routine for irq 11 hwint_slave 11 ALIGN 16 hwint12: ; Interrupt routine for irq 12 hwint_slave 12 ALIGN 16 hwint13: ; Interrupt routine for irq 13 (FPU exception) hwint_slave 13 ALIGN 16 hwint14: ; Interrupt routine for irq 14 (AT winchester) hwint_slave 14 ALIGN 16 hwint15: ; Interrupt routine for irq 15 hwint_slave 15 ; 中断和异常 -- 异常 divide_error: push 0xFFFFFFFF ; no err code push 0 ; vector_no = 0 jmp exception single_step_exception: push 0xFFFFFFFF ; no err code push 1 ; vector_no = 1 jmp exception nmi: push 0xFFFFFFFF ; no err code push 2 ; vector_no = 2 jmp exception breakpoint_exception: push 0xFFFFFFFF ; no err code push 3 ; vector_no = 3 jmp exception overflow: push 0xFFFFFFFF ; no err code push 4 ; vector_no = 4 jmp exception bounds_check: push 0xFFFFFFFF ; no err code push 5 ; vector_no = 5 jmp exception inval_opcode: push 0xFFFFFFFF ; no err code push 6 ; vector_no = 6 jmp exception copr_not_available: push 0xFFFFFFFF ; no err code push 7 ; vector_no = 7 jmp exception double_fault: push 8 ; vector_no = 8 jmp exception copr_seg_overrun: push 0xFFFFFFFF ; no err code push 9 ; vector_no = 9 jmp exception inval_tss: push 10 ; vector_no = A jmp exception segment_not_present: push 11 ; vector_no = B jmp exception stack_exception: push 12 ; vector_no = C jmp exception general_protection: push 13 ; vector_no = D jmp exception page_fault: push 14 ; vector_no = E jmp exception copr_error: push 0xFFFFFFFF ; no err code push 16 ; vector_no = 10h jmp exception exception: call exception_handler add esp, 4*2 ; 让栈顶指向 EIP,堆栈中从顶向下依次是:EIP、CS、EFLAGS hlt ; 一堆符号导出,没别的 global restart ; 异常处理 global divide_error global single_step_exception global nmi global breakpoint_exception global overflow global bounds_check global inval_opcode global copr_not_available global double_fault global copr_seg_overrun global inval_tss global segment_not_present global stack_exception global general_protection global page_fault global copr_error ; 外设中断 global hwint00 global hwint01 global hwint02 global hwint03 global hwint04 global hwint05 global hwint06 global hwint07 global hwint08 global hwint09 global hwint10 global hwint11 global hwint12 global hwint13 global hwint14 global hwint15