06 Windows线程切换——时钟中断

1、如何中断一个正在执行的程序
<1>异常 比如缺页,或者INT N指令
<2>中断 比如时钟中断

2、系统时钟

(IDT表)中断号 IRQ 说明
0x30 IRQ0 时钟中断

Windows系列操作系统,10-20毫秒
如何获取当前时钟中断间隔值,可以使用Win32API:GetSystemTimeAdjustment()

3、时钟中断系统发生的流程
KiStartUnexpectedRange()
KiEndUnexpectedRange()
KiUnexpectedInterruptRange()
HalBeginSystemInterrupt()
HalEndSystemInterrupt()
KiDispatchInterrupt()
SwapContext()
接下来我们看一下当时钟中断系统执行流程是咋样的,首先我们在IDA中Alt+T搜索_IDT如下:
06 Windows线程切换——时钟中断
接着找到KiStartUnexpectedRange()函数:
06 Windows线程切换——时钟中断
跳到KiEndUnexpectedRange()
06 Windows线程切换——时钟中断
06 Windows线程切换——时钟中断
接着查看上面两个函数是在hal.dll模块里的,用ida打开hal.dll
06 Windows线程切换——时钟中断
06 Windows线程切换——时钟中断
06 Windows线程切换——时钟中断
接下来我们会到内核模块看下这个函数
06 Windows线程切换——时钟中断
来到这个函数我们就看到了切换线程的函数,所以当时钟中断发生时,也会导致线程的切换

3、总结
线程切换的几种情况
<1>主动调用API函数
<2>时钟中断
<3>异常处理
如果一个线程不调用API,在代码中屏蔽中断指令(CLI),并且不会出现异常,那么当前线程将永久占有CPU,单核占有率100%,二核占有率就是50%