通过上面的分析,发现设置一个中断处理是非常复杂的,下面就来通过图来分析一个中断发生时,中断处理的过程如下图:@H_404_5@
@H_404_5@
@H_404_5@
其实所有上面代码,就是设置这些流程里工作的函数关键代码,以便整个中断连接起来。其中一些函数是在汇编代码里面,这些都需要仔细分析才能理解。@H_404_5@
@H_404_5@
#001 .func KiInterruptTemplate@H_404_5@
#002 _KiInterruptTemplate:@H_404_5@
#003 @H_404_5@
#004 /* Enter interrupt trap */@H_404_5@
#005 INT_PROLOG kit_a,kit_t,DoPushFakeErrorCode@H_404_5@
#006 @H_404_5@
#007 _KiInterruptTemplate2ndDispatch:@H_404_5@
#008 /* Dummy code,will be replaced by the address of the KINTERRUPT */@H_404_5@
#009 mov edi,0@H_404_5@
#010 @H_404_5@
#011 _KiInterruptTemplateObject:@H_404_5@
#012 /* Dummy jump,will be replaced by the actual jump */@H_404_5@
#013 jmp _KeSynchronizeExecution@12@H_404_5@
#014 @H_404_5@
#015 _KiInterruptTemplateDispatch:@H_404_5@
#016 /* Marks the end of the template so that the jump above can be edited */@H_404_5@
#017 @H_404_5@
#018 TRAP_FIXUPS kit_a,DoFixupV86,DoFixupAbios@H_404_5@
#019 .endfunc@H_404_5@
@H_404_5@
和@H_404_5@
@H_404_5@
#001 .func KiInterruptDispatch@0@H_404_5@
#002 _KiInterruptDispatch@0:@H_404_5@
#003 @H_404_5@
#004 /* Increase interrupt count */@H_404_5@
#005 inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]@H_404_5@
#006 @H_404_5@
#007 /* Save trap frame */@H_404_5@
#008 mov ebp,esp@H_404_5@
#009 @H_404_5@
#010 /* Save vector and IRQL */@H_404_5@
#011 mov eax,[edi+KINTERRUPT_VECTOR]@H_404_5@
#012 mov ecx,[edi+KINTERRUPT_SYNCHRONIZE_IRQL]@H_404_5@
#013 @H_404_5@
#014 /* Save old irql */@H_404_5@
#015 push eax@H_404_5@
#016 sub esp,4@H_404_5@
#017 @H_404_5@
#018 /* Begin interrupt */@H_404_5@
#019 push esp@H_404_5@
#020 push eax@H_404_5@
#021 push ecx@H_404_5@
#022 call _HalBeginSystemInterrupt@12@H_404_5@
#023 @H_404_5@
#024 /* Check if it was handled */@H_404_5@
#025 or al,al@H_404_5@
#027 @H_404_5@
#028 /* Acquire the lock */@H_404_5@
#029 GetIntLock:@H_404_5@
#030 mov esi,[edi+KINTERRUPT_ACTUAL_LOCK]@H_404_5@
#031 ACQUIRE_SPINLOCK(esi,IntSpin)@H_404_5@
#032 @H_404_5@
#033 /* Make sure that this interrupt isn't storming */@H_404_5@
#034 VERIFY_INT kid@H_404_5@
#035 @H_404_5@
#036 /* Save the tick count */@H_404_5@
#037 mov ebx,_KeTickCount@H_404_5@
#038 @H_404_5@
#039 /* Call the ISR */@H_404_5@
#040 mov eax,[edi+KINTERRUPT_SERVICE_CONTEXT]@H_404_5@
#041 push eax@H_404_5@
#042 push edi@H_404_5@
#043 call [edi+KINTERRUPT_SERVICE_ROUTINE]@H_404_5@
#044 @H_404_5@
#045 /* Check if the ISR timed out */@H_404_5@
#046 add ebx,_KiISRTimeout@H_404_5@
#047 cmp _KeTickCount,ebx@H_404_5@
#048 jnc IsrTimeout@H_404_5@
#049 @H_404_5@
#050 ReleaseLock:@H_404_5@
#051 /* Release the lock */@H_404_5@
#052 RELEASE_SPINLOCK(esi)@H_404_5@
#053 @H_404_5@
#054 /* Exit the interrupt */@H_404_5@
#055 INT_EPILOG 0@H_404_5@
#056 @H_404_5@
#058 /* Exit the interrupt */@H_404_5@
#059 add esp,8@H_404_5@
#060 INT_EPILOG 1@H_404_5@
#061 @H_404_5@
#062 #ifdef CONFIG_SMP@H_404_5@
#063 IntSpin:@H_404_5@
#064 SPIN_ON_LOCK(esi,GetIntLock)@H_404_5@
#065 #endif@H_404_5@
#066 @H_404_5@
#067 IsrTimeout:@H_404_5@
#068 /* Print warning message */@H_404_5@
#069 push [edi+KINTERRUPT_SERVICE_ROUTINE]@H_404_5@
#070 push offset _IsrTimeoutMsg@H_404_5@
#071 call _DbgPrint@H_404_5@
#072 add esp,8@H_404_5@
#073 @H_404_5@
#074 /* Break into debugger,then continue */@H_404_5@
#075 int 3@H_404_5@
#076 jmp ReleaseLock@H_404_5@
#077 @H_404_5@
#078 /* Cleanup verification */@H_404_5@
#079 VERIFY_INT_END kid,0@H_404_5@
#080.endfunc@H_404_5@