在ReactOS里使用下面这行代码来设置IDTR寄存器的值:
Ke386SetInterruptDescriptorTable(*(PKDESCRIPTOR)&KiIdtDescriptor.Limit);
具体的获取地址如下图所示:
上面这行代码,就把中断描述符表加载到IDTR寄存器,这样就设置好中断表。那么在ReactOS中断表描述符的基地址是多少呢?从上图可以看到它是_KiIdt地址,它是在文件reactos/ntoskrnl/ke/i386/trap.s里,如下所示:
#001 /* GLOBALS *******************************************************************/
#002
#003 .data
#004 .globl _KiIdt
#005 _KiIdt:
#006 /* This is the Software Interrupt Table that we handle in this file: */
#007 idt _KiTrap0, INT_32_DPL0 /* INT 00: Divide Error (#DE) */
#008 idt _KiTrap1, INT_32_DPL0 /* INT 01: Debug Exception (#DB) */
#009 idt _KiTrap2, INT_32_DPL0 /* INT 02: NMI Interrupt */
#010 idt _KiTrap3, INT_32_DPL3 /* INT 03: Breakpoint Exception (#BP) */
#011 idt _KiTrap4, INT_32_DPL3 /* INT 04: Overflow Exception (#OF) */
#012 idt _KiTrap5, INT_32_DPL0 /* INT 05: BOUND Range Exceeded (#BR) */
#013 idt _KiTrap6, INT_32_DPL0 /* INT 06: Invalid Opcode Code (#UD) */
#014 idt _KiTrap7, INT_32_DPL0 /* INT 07: Device Not Available (#NM) */
#015 idt _KiTrap8, INT_32_DPL0 /* INT 08: Double Fault Exception (#DF) */
#016 idt _KiTrap9, INT_32_DPL0 /* INT 09: RESERVED */
#017 idt _KiTrap10, INT_32_DPL0 /* INT
#018 idt _KiTrap11, INT_32_DPL0 /* INT 0B: Segment Not Present (#NP) */
#019 idt _KiTrap12, INT_32_DPL0 /* INT
#020 idt _KiTrap13, INT_32_DPL0 /* INT 0D: General Protection (#GP) */
#021 idt _KiTrap14, INT_32_DPL0 /* INT 0E: Page-Fault Exception (#PF) */
#022 idt _KiTrap
#023 idt _KiTrap16, INT_32_DPL0 /* INT 10: x87 FPU Error (#MF) */
#024 idt _KiTrap17, INT_32_DPL0 /* INT 11: Align Check Exception (#AC) */
#025 idt _KiTrap
#026 idt _KiTrap
#027 .rept 22
#028 idt _KiTrap
#029 .endr
#030 idt _KiGetTickCount, INT_32_DPL3 /* INT
#031 idt _KiCallbackReturn, INT_32_DPL3 /* INT 2B: User-Mode Callback Return */
#032 idt _KiRaiseAssertion, INT_32_DPL3 /* INT
#033 idt _KiDebugService, INT_32_DPL3 /* INT 2D: Debug Service Handler */
#034 idt _KiSystemService, INT_32_DPL3 /* INT 2E: System Call Service Handler */
#035 idt _KiTrap
#036 GENERATE_IDT_STUBS /* INT 30-FF: UNEXPECTED INTERRUPTS */
#037
上面就是ReactOS所有中断处理的中断表,每个中断里都处理中断服务函数。这里特别关心的,可能就是KiGetTickCount和KiSystemService这两个中断函数了,第一个是硬件的时间片中断服务,第二个是从应用程序到ReactOS系统调用服务,也就是内核提供的API功能入口点,也是应用使用内核提供功能的入口点。
通上面这行代码,就可以把中断描述符表设置到CPU的IDTR寄存器,实现了ReactOS中断调用初始化,只有这样初始化之后,才能允许打开中断,否则系统运行就出错了。