在 DOS 實模式下,透過攔截 INT 08h(定時器中斷)實作抽佔式多任務核心。核心資料結構:
TCB(Task Control Block):儲存堆疊指標(SS:SP)、狀態、名稱、訊息佇列、同步物件。semaphore:計數值 + 等待佇列,實作 P/V 操作。buffer:固定大小訊息緩衝區,形成自由鏈表與各任務私有佇列。int create(char *name, codeptr code, int stck) {
// 分配堆疊、初始化偽堆疊幀(含 flags=0x200 啟用中斷、返回位址指向 over())
// 設定狀態 READY,加入 TCB 陣列
}
void over() { destory(current); swtch(); } // 任務結束自動銷毀
swtch()yield 或阻塞時切換。INT 08h 新處理常式 new_int8 遞減 timecount,歸零觸發 swtch()。iret 返回新任務。void p(semaphore *sem) { disable(); if (--sem->value < 0) block(&sem->wq); enable(); }
void v(semaphore *sem) { disable(); if (++sem->value <= 0) wakeup(&sem->wq); enable(); }
mutex(初值 1):互斥鎖。sfb(初值 NBUF):生產者-消費者空槽計數。sa/sb(初值 1/0):雙緩衝區同步。send(receiver, data, size):從自由鏈表取 buffer,填入資料,掛入接收者 mq,v(&sm) 喚醒接收者。receive(sender, buf):p(&sm) 等待訊息,從 mq 取出對應 sender 的 buffer,複製資料,歸還 buffer 到自由鏈表,v(&sfb) 釋放空槽。DOS 非重入,核心透過 INDOS 標誌(INT 21h, AH=34h 取得)檢測 DOS 是否忙碌,DosBusy() 回傳非零時延遲任務切換,避免破壞 DOS 內部狀態。
原始碼針對 Turbo C 2.0,使用 far 指標、interrupt 關鍵字、disable()/enable() 關中斷。現代環境可在 DOSBox 或 FreeDOS 中編譯執行。