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

組語原始碼系列:DOS 時鐘常駐程式 (CLOCK.ASM)

     編輯:組合語言

前言

這是一個經典的 DOS 時代組語範例:常駐記憶體 (TSR) 程式,攔截計時器中斷 (INT 1Ch) 在螢幕右上角即時顯示時鐘。雖然 DOS 已成歷史,但其中的中斷鏈結、視訊記憶體直接操作、TSR 終止並常駐 (INT 27h) 等技術,對理解底層硬體控制作業系統原理仍具教學價值。

程式架構

  • 資料區:儲存舊中斷向量、滴答計數器、螢幕位移、CRT 狀態埠、時間字串緩衝區。
  • CLK_INT:新的計時器中斷處理常式,每 18.2 次/秒被呼叫。
    • 呼叫原中斷處理常式(維持系統計時功能)。
    • 遞增滴答計數器,約 20 個滴答(約 1 分鐘)更新一次時間。
    • 等待垂直回掃期間寫入視訊記憶體(單色/彩色自動偵測),避免畫面閃爍。
  • UPDATE:將 BIOS 計時器讀取的二進位時間轉換為 ASCII 字串(時:分 AM/PM)。
  • SETUP:安裝中斷向量、偵測視訊模式、呼叫首次 UPDATE、以 INT 27h 終止並常駐 (TSR)。

關鍵技術點

  1. 中斷向量表 (IVT) 操作:SIDT 取得 IDT 基址(保護模式),本程式為實模式直接操作 0:0070h (INT 1Ch)。
  2. 視訊記憶體直接寫入:單色 B000:0000、彩色 B800:0000,透過 CRT 狀態埠 (0x3BA/0x3DA) 同步垂直回掃。
  3. TSR 終止並常駐:INT 27h 以 DX 指定常駐記憶體末端(含程式碼、資料、PSP)。
  4. 雙重中斷鏈結:同時攔截 INT 1Ch (計時器) 與 INT 1Bh (Ctrl-Break),確保在鍵盤中斷也能更新顯示。

原始碼精簡版(註解重點)

CODESEG SEGMENT PARA
ASSUME CS:CODESEG, DS:CGROUP
ORG 100h
CLK PROC FAR
    JMP SETUP
INTRPT LABEL DWORD
    INT_IP DW 0
    INT_CS DW 0
TICKS DW 0
SCR_OFF DB 0,0
CRT_PORT DW 0
TIME DB 8 DUP(':',0Bh)
CLK_INT:
    PUSH AX, CX, DI, SI, DS, ES
    PUSHF
    CALL CS:[INTRPT]          ; 呼叫原 INT 1Ch
    ; ... 更新 TICKS,每 20 滴答呼叫 UPDATE ...
    ; ... 等待垂直回掃,將 TIME 寫入 ES:[DI] (視訊記憶體) ...
    POP ES, DS, SI, DI, CX, AX
    IRET
UPDATE PROC NEAR
    ; 從 0040h:006Ch 讀取 BIOS 計時器,轉換為 時:分 AM/PM 存入 TIME
    RET
UPDATE ENDP
SETUP:
    ; 取得舊 INT 1Ch 向量存入 INTRPT
    ; 偵測視訊模式設定 CRT_PORT、SCR_OFF
    CALL UPDATE
    MOV DX, OFFSET SETUP      ; 常駐區塊結束位址
    INT 27h                   ; TSR
CODESEG ENDS
END CLK

歷史背景與現代對應

  • DOS 實模式下,所有程式共享中斷向量表,TSR 技術廣泛用於螢幕保護、熱鍵工具、網路驅動等。
  • 現代 Windows 使用保護模式、硬體抽象層 (HAL)、驅動程式模型,不再允許應用程式直接攔截硬體中斷或寫入視訊記憶體。
  • 類似功能今透過 Windows Timer (SetTimer)、GDI/DirectX 繪圖、系統通知區圖示實現。

學習建議

研讀此類古早程式碼可訓練:

  1. 中斷處理常式撰寫規範(保存/恢復暫存器、盡量精簡)。
  2. 硬體資源直接操作(連接埠 I/O、記憶體映射 I/O)。
  3. 記憶體佈局與常駐機制理解。

雖不再實用,但為作業系統、嵌入式系統、逆向工程基礎訓練的優良教材。

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