本文收錄 BRK2.ASM,為 BRK 的增強版,提供完整的 Ctrl-Break 處理模組介面:安裝/移除處理常式、保存/恢復舊向量、封裝檢查函數 (自動歸零旗標)。採用標準 DOS 中斷管理流程 (AH=35h/25h)、模組化公開介面 (PUBLIC 4 函數)、結構化資料段。展示專業級 TSR/工具程式的中斷處理最佳實踐。
TITLE BRK2 -- Break Handling Utilities Module
TRUE EQU 01H
FALSE EQU 00H
BREAKINT EQU 23H
GETVECTOR EQU 35H
SETVECTOR EQU 25H
DOS_FUNCTION EQU 21H
BREAK SEGMENT PUBLIC 'CODE'
BREAKFLAG DB 0H
SAVEBRK DD 0H
ASSUME CS:BREAK
ASSUME DS:NOTHING
PUBLIC CHECK_BREAK
CHECK_BREAK PROC FAR
XOR AX, AX
MOV AL, BREAKFLAG
MOV BREAKFLAG, FALSE
RET
CHECK_BREAK ENDP
PUBLIC INST_BRK_HANDLR
INST_BRK_HANDLR PROC FAR
PUSH DS
MOV AL, BREAKINT
MOV AH, GETVECTOR
INT DOS_FUNCTION
MOV WORD PTR SAVEBRK, BX
MOV WORD PTR SAVEBRK+2, ES
MOV AL, BREAKINT
MOV AH, SETVECTOR
MOV DX, OFFSET BRK_HANDLER
MOV BX, CS
MOV DS, BX
INT DOS_FUNCTION
POP DS
RET
INST_BRK_HANDLR ENDP
BRK_HANDLER PROC FAR
MOV BREAKFLAG, TRUE
IRET
BRK_HANDLER ENDP
REM_BRK_HANDLR PROC FAR
PUSH DS
MOV AL, BREAKINT
MOV AH, SETVECTOR
MOV DX, WORD PTR SAVEBRK
MOV BX, WORD PTR SAVEBRK+2
MOV DS, BX
INT DOS_FUNCTION
POP DS
RET
REM_BRK_HANDLR ENDP
BREAK ENDS
END
| 函數 | 功能 | 關鍵邏輯 |
|---|---|---|
CHECK_BREAK | 檢查並清除旗標 | AL = BREAKFLAG; BREAKFLAG = FALSE 返回前狀態並歸零 |
INST_BRK_HANDLR | 安裝新處理常式 | 1. AH=35h 取得舊向量存入 SAVEBRK2. AH=25h 設定新向量指向 BRK_HANDLER |
BRK_HANDLER | 中斷處理常式 | BREAKFLAG = TRUE; IRET 極簡、安全 |
REM_BRK_HANDLR | 移除並恢復舊向量 | AH=25h, DS:DX = SAVEBRK 恢復原始向量 |
SAVEBRK DD 0H ; 4 位元組:位移 (WORD) + 段基址 (WORD)
; 保存
MOV WORD PTR SAVEBRK, BX ; BX = 位移
MOV WORD PTR SAVEBRK+2, ES ; ES = 段基址
; 恢復
MOV DX, WORD PTR SAVEBRK ; DX = 位移
MOV BX, WORD PTR SAVEBRK+2 ; BX = 段基址
MOV DS, BX ; DS = 段基址 (SETVECTOR 需 DS:DX)
DD 定義雙字 (4 位元組) 儲存完整遠指標WORD PTR 取低/高字SETVECTOR (AH=25h) 需 DS:DX 指向新處理常式
BRK_HANDLER PROC FAR
MOV BREAKFLAG, TRUE
IRET
BRK_HANDLER ENDP
BREAKFLAG 記憶體,不影響可見暫存器)IRET 正確恢復 CS:IP, FLAGS
CHECK_BREAK PROC FAR
XOR AX, AX
MOV AL, BREAKFLAG
MOV BREAKFLAG, FALSE
RET
CHECK_BREAK ENDP
AL=1 表示自上次檢查以來有過 Ctrl-Breakif (check_break()) handle_break();
BREAK SEGMENT PUBLIC 'CODE'
ASSUME CS:BREAK
ASSUME DS:NOTHING
PUBLIC 'CODE':程式碼類別,連結器歸入 CODE 群組ASSUME DS:NOTHING:明確宣告 DS 不指向固定段,需在函數內動態設定 (如 MOV AX,DGROUP; MOV DS,AX 或 MOV BX,CS; MOV DS,BX)CHECK_BREAK 統一「讀取+歸零」語義,呼叫端無需知曉旗標變數PUBLIC 4 函數,可獨立組譯為 .OBJ,連結進任意專案EQU 定義中斷號、功能碼,可讀性與維護性大增| BRK2 模組 | 現代對應 |
|---|---|
INST_BRK_HANDLR | signal(SIGINT, handler) / SetConsoleCtrlHandler / AddVectoredExceptionHandler |
REM_BRK_HANDLR | signal(SIGINT, SIG_DFL) / RemoveVectoredExceptionHandler |
CHECK_BREAK | atomic_flag_test_and_set / CancellationToken.IsCancellationRequested |
SAVEBRK 雙字遠指標 | 函數指標 / std::function / 委派 / 閉包 |
| 中斷處理常式極簡 | 信號處理器只設旗標 / async-signal-safe 函數限制 |
AH=35h (GETVECTOR) / AH=25h (SETVECTOR)DD/WORD PTR/DS:DX 傳遞FAR PROC、最小指令數、無系統呼叫、IRETSET → POLL+CLEAR (生產者-消費者單緩衝)SEGMENT PUBLIC/ASSUME/PUBLIC/EQU 常數化BRK2.ASM 將簡易版 BRK 升級為工業級中斷處理模組:向量保存/恢復保證系統穩定、封裝介面簡化呼叫端邏輯、常數化提升可維護性、極簡處理常式確保即時性。其設計模式——安裝/移除成對、狀態封裝、向量鏈接尊重、處理常式極簡——直接映射到現代作業系統的信號處理、異常處理、向量化異常處理機制。研讀此碼,可建立「非同步事件同步化處理」的正統架構觀。