BREAK.ASM 為 Lattice C 編譯器提供的組語模組,讓 C 程式能捕獲使用者按下 Ctrl+C 或 Ctrl+Break,避免程式被 DOS 強制終止。透過攔截兩個中斷向量:
提供兩個 C 可呼叫函數:
capture(int *flag):安裝中斷處理常式,flag 為 C 程式中靜態整數變數位址,發生 Ctrl-Break 時設為 -1 (TRUE)。release(void):還原原始中斷向量,恢復預設行為 (通常是終止程式)。capture proc near
push bp; mov bp, sp
push ds
mov ax, word ptr [bp+args] ; 取 flag 位址 (依大/小模型 args=4/6)
mov cs:flag, ax
mov cs:flag+2, ds ; 存 flag 遠端址
; 取得原 INT 23h 向量
mov ax, 3523h; int 21h
mov cs:int23, bx; mov cs:int23+2, es
; 取得原 INT 1Bh 向量
mov ax, 351Bh; int 21h
mov cs:int1b, bx; mov cs:int1b+2, es
; 設定新向量指向 ctrlbrk
push cs; pop ds
mov dx, offset ctrlbrk
mov ax, 2523h; int 21h
mov ax, 251Bh; int 21h
pop ds; pop bp; ret
capture endp
ctrlbrk proc far ; 中斷處理常式
push bx; push ds
mov bx, cs:flag
mov ds, cs:flag+2
mov word ptr ds:[bx], -1 ; 設 flag = TRUE
pop ds; pop bx
iret
ctrlbrk endp
release proc near ; 還原向量
push bp; mov bp, sp
push ds
mov dx, cs:int1b; mov ds, cs:int1b+2
mov ax, 251Bh; int 21h
mov dx, cs:int23; mov ds, cs:int23+2
mov ax, 2523h; int 21h
pop ds; pop bp; ret
release endp
flag 為雙字 (段:位移),因 C 程式可能在不同區段 (大模型)。ctrlbrk 可能在鍵盤中斷內執行 (非同步),嚴禁呼叫 DOS 功能 (INT 21h),否則導致系統崩潰。僅執行極簡單操作:設旗標。if lprog 判斷大/小模型,調整參數堆疊偏移 args。release。static int break_flag = 0;
int main() {
capture(&break_flag);
while (!break_flag) {
// 主迴圈運算
}
release();
printf("User pressed Ctrl+Break\n");
return 0;
}
SetConsoleCtrlHandler 捕獲 CTRL_C_EVENT、CTRL_BREAK_EVENT,原理類似但由作業系統管理執行緒同步。signal(SIGINT, handler)。