首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

組合語言編寫 DOS 記憶體駐留程式(TSR):鍵盤輸入擴充實戰(五)

     編輯:組合語言

五、鍵盤輸入擴充程式:按鍵宏與熱鍵的核心技術

基於基本 TSR 架構,開發鍵盤擴充程式:將特定按鍵替換為預定字串序列,減少用戶擊鍵。核心挑戰:攔截 INT 16H(鍵盤 BIOS 服務)、識別擴充鍵、管理擴充字串輸出狀態、欺騙 DOS 鍵盤狀態檢查。

1. 擴充鍵選擇:擴充碼(Extended Keycode)最安全

普通字母數字作擴充鍵易衝突;控制碼被 DOS 佔用(如 Ctrl+H)。IBM PC 擴充鍵(功能鍵 F1-F10、Alt 組合、Shift/Ctrl 組合)雙碼編碼(首碼 0),DOS 易分辨,且不影響正常操作。附表列出 1-132 號擴充碼對應鍵位(如 59=F1, 60=F2... 84=Shift+F1... 104=Alt+F1...)。

2. 字串結尾標記:ASCIIZ(0 結尾)最通用

  • CR (0DH):邏輯直觀但難表達多行。
  • $:DOS 系統呼叫常用作結尾,字串中不可含 $。
  • ASCII 0:C 語言標準,可表達所有可見/不可見字元,鍵盤無法輸入 0,最安全。

3. 核心機制:狀態機管理擴充輸出

使用指標 current 指向下一個待輸出字元:

  • current = 0:無擴充進行,正常讀取鍵盤。
  • current ≠ 0:擴充中,依序輸出字串字元,遇 0 歸零並恢復讀取真實鍵盤。

關鍵點:INT 16H AH=1(狀態檢查)必須在擴充時強制回傳「有字元」(ZF=0)。IRET 會從堆疊恢復旗標,故須用 RET 2 丟棄中斷進入時自動壓入的旗標,以保留修改後的 ZF。

4. 單鍵擴充完整範例:F1 → "DIR" + Enter

; 關鍵變數
current dw 0
string  db 'DIR', 0dh, 0

; KeyRead 核心邏輯
KeyRead proc
    cmp cs:current, 0
    jne ExpandChar
ReadChar:
    mov cs:current, 0
    pushf
    call Old_Keyboard_IO
    cmp al, 0
    je Extended
    ret
Extended:
    cmp ah, 59          ; F1 擴充碼
    jne ReadDone
    mov cs:current, offset string
ExpandChar:
    push si
    mov si, cs:current
    mov al, cs:[si]
    inc cs:current
    pop si
    cmp al, 0
    je ReadChar
    ret
KeyRead endp

; KeyStat:擴充中強制 ZF=0
KeyStat proc
    cmp cs:current, 0
    jne FakeStat
    pushf
    call Old_Keyboard_IO
    ret
FakeStat:
    mov bx, 1
    cmp bx, 0           ; 清 ZF
    ret
KeyStat endp

注意:mov cs:current, offset string 取位址,非 mov cs:current, string(後者錯誤移動字元內容)。記憶體存取必須基於 CS(cs:current),因進入 TSR 時 DS 不可知且必須保留給被中斷程式。

5. 多鍵擴充:查表法大幅節省記憶體

單鍵獨立 TSR 疊加層層攔截,128 鍵需 13KB 代碼。改用單一 TSR 內建查表:

  • 鍵表:db 擴充碼, dw 字串位址,以 db 0 結束。
  • 128 鍵約 284 位元組表頭 + 50 位元組代碼 + 字串空間(假設 20 字元/鍵 ≈ 2.5KB),總計 <3KB,較疊加法省 10KB。
  • KeyRead 掃描鍵表比對 AH,命中則載入對應字串位址至 current。

初始化時可從設定檔載入鍵表,載入代碼執行後可丟棄,不佔駐留空間。

6. 通用鍵盤擴充程式 Mactab.asm 完整架構

包含:New_Keyboard_IO(主攔截器)、KeyRead(查表+狀態機)、KeyStat(偽裝狀態)、Initialize(攔截 INT 16H、TSR 駐留)、鍵表與字串資料區。代碼結構清晰,易於擴展維護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved