ihandler.cpp ihandler.asm 割り込みハンドラ cppファイルとasmファイルで構成されている。 割り込みプロシージャはカーネルのコードセグメントの中に入っている。このセグメントの 設定では処理が移ると特権レベルの以降があるので場合によってはスタックの切り替えが 起こる。 タイマイベントの割り込み ユーザーコードから割り込まれた場合とカーネルコードから割り込まれた場合とで スタックの状況が異なる。 ユーザーコードから割り込まれた場合 呼び出し側SS、呼び出し側ESP、呼び出し側CS、呼び出し側EIPの順にプッシュされている。 HIGH | | |呼び出し側SS | |呼び出し側ESP | |フラグレジスタ | |呼び出し側CS | |呼び出し側EIP |←呼び出された時点でのESP | | LOW まず、マクロpushALLが実行される。これはスタックに EAX, ECX, EDX, EBX, 元のESP, EBP, ESI, EDI, DS, ESをこの順番にプッシュしている。 HIGH | | |呼び出し側SS | |呼び出し側ESP | |フラグレジスタ | |呼び出し側CS | |呼び出し側EIP |←呼び出された時点でのESP |EAX | |ECX | |EDX | |EBX | |ESP |(呼び出された時点でのESPが入っていることになる。) |EBP | |ESI | |EDI | |DS | |ES | | | LOW 次にchangeDataでDSとESをカーネル領域の変数にアクセスできるように設定している。 その次にarch_save_thread_registers を呼び出してスレッドのレジスタを保存している。 スレッドのレジスタは大体スタックに納められている形になっているからこのプロシージャは スタックを参照して所定の領域にレジスタ情報を格納している。なお、このプロシージャは core.asmにある。すべてのレジスタ情報を格納し終えたらtimerHandlerを呼び出して 実際の処理に移る。 ;;; timer handler ;;; save all context to Kthread* current arch_timerhandler: pushAll changeData call arch_save_thread_registers call timerHandler popAll iretd void timerHandler() { /* EOI */ outportb(0x20, 0x20); g_scheduler->tick(); g_currentThread->thread->tick(); bool isProcessChange = g_scheduler->schedule(); ThreadOperation::switchThread(isProcessChange, 1); /* does not come here */ }