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

DOS 時代組合語言經典原始碼賞析:CLEAN 文字檔過濾工具

     編輯:組合語言

前言

本文收錄 Ray Duncan 1983 年編寫的 CLEAN.ASM,功能為過濾文字檔:移除控制碼 (保留 LF/CR/FF)、去除高位元、展開 Tab 為空白、附加 EOF 標記。支援區塊讀寫 (1KB 緩衝區)、命令列參數解析、錯誤處理、進度顯示。展示了 DOS 2.0 檔案控制代碼 API (INT 21h AH=3Ch/3Dh/3Fh/40h/3Eh)、緩衝區管理、字元級處理邏輯、模組化程式結構。

程式功能與流程

  1. 解析命令列取得輸入檔名
  2. 自動產生輸出檔名:同名改副檔名為 .CLN
  3. 開啟輸入檔 (唯讀) / 建立輸出檔 (寫入/截斷)
  4. 初始化 1KB 輸入/輸出緩衝區
  5. 迴圈逐字元讀取、過濾、寫入:
讀字元 → AND 7Fh (去高位)
→ 若 >= 20h : 正常字元 → 寫入、欄位計數++
→ 若控制碼 :
    EOF(1Ah) : 結束
    Tab(09h) : 展開至下一 8 欄位倍數 (送空白)
    CR/LF/FF : 寫入、欄位歸零
    其他 : 捨棄
→ 緩衝區滿寫入磁碟
  • 偵測磁碟已滿、檔案不存在等錯誤並顯示訊息
  • 關閉檔案、顯示完成訊息
  • 核心模組與關鍵技術

    1. 檔案 I/O 區塊讀寫 (1KB 緩衝)

    ; 讀取區塊
    read_block:
     mov bx, input_handle
     mov cx, blksize (1024)
     mov dx, offset input_buffer
     mov ah, 3fh
     int 21h
    ; 寫入區塊
    write_block:
     mov bx, output_handle
     mov cx, blksize
     mov dx, offset output_buffer
     mov ah, 40h
     int 21h
    
    • get_char/put_char 管理緩衝區指標,滿/空時呼叫區塊讀寫。
    • 讀取不足 1KB 時在緩衝區末尾植入 EOF (1Ah) 標記,簡化主迴圈判斷。
    • 寫入時檢查實際寫入位元組數,CY=1 表示磁碟已滿。

    2. Tab 展開演算法

    clean5:          ; 處理 Tab
     mov ax, column
     cwd
     mov cx, 8
     idiv cx         ; AX=商, DX=餘數
     sub cx, dx      ; 8 - 餘數 = 需補空白數
     add column, cx  ; 更新欄位計數
    clean55:
     push cx
     mov al, 20h     ; 空白
     call put_char
     pop cx
     loop clean55
    

    將目前欄位數對 8 取餘,補足至下一個 8 的倍數。

    3. 命令列解析與檔名處理

    • infile:跳過前導空白,複製至 CR 或空白前,存入 input_name。
    • outfile:複製 input_name,掃描 '.' 或結尾,強制改為 .CLN。

    4. 錯誤處理與使用者介面

    • 各檔案操作檢查 CY 旗標,失敗顯示對應訊息 (msg1~msg5)。
    • sign_on 顯示標題、版權、輸入/輸出檔名。
    • pasciiz 列印 ASCIIZ 字串 (以 0 結尾),並將大寫轉小寫顯示。

    完整原始碼結構概覽

    cseg segment ...          ; 程式碼段
    clean proc far            ; 進入點
     infile, outfile          ; 檔名處理
     open_input, open_output  ; 檔案開啟
     init_buffs               ; 緩衝區初始化
     sign_on                  ; 顯示資訊
    clean3:                   ; 主過濾迴圈
     get_char, put_char       ; 緩衝字元存取
     read_block, write_block  ; 區塊磁碟 I/O
     flush_buffs              ; 寫入剩餘緩衝資料
     close_input, close_output
     sign_on, pasciiz         ; 訊息顯示
    cseg ends
    
    data segment ...          ; 資料段
     input_name, output_name  ; 檔名緩衝
     input_handle, output_handle
     input_ptr, output_ptr    ; 緩衝區指標
     column                   ; 欄位計數 (Tab用)
     msg1~msg9                ; 各類訊息
     input_buffer, output_buffer (1024 bytes each)
    data ends
    
    stack segment ...         ; 堆疊段
    stack ends
    end clean
    

    DOS 2.0 檔案 API 對照表

    現代對應與啟發

    功能AH輸入輸出
    建立/截斷檔案3ChDS:DX=檔名, CX=屬性AX=控制代碼
    開啟檔案3DhDS:DX=檔名, AL=模式AX=控制代碼
    讀取檔案3FhBX=控制代碼, CX=位元組數, DS:DX=緩衝區AX=實際讀取位元組數
    寫入檔案40hBX=控制代碼, CX=位元組數, DS:DX=緩衝區AX=實際寫入位元組數
    關閉檔案3EhBX=控制代碼無
    CLEAN 技術現代對應
    1KB 區塊緩衝 I/O標準庫 fread/fwrite、BufferedReader/Writer、mmap
    字元級過濾管線串流處理 (Stream API、Reactive Streams、Pipes)
    Tab 展開演算法編輯器/終端機渲染引擎核心邏輯
    命令列解析getopt/argparse/CLI11
    錯誤碼旗標檢查例外處理 / Result/Either 型別 / errno
    ASCIIZ 字串處理C 風格字串 / std::string_view / Rust &str

    學習重點

    • DOS 檔案控制代碼機制與 INT 21h 3Ch/3Dh/3Fh/40h/3Eh 完整流程
    • 雙緩衝區 (輸入/輸出) 管理:指標追蹤、滿/空觸發區塊 I/O、殘留資料刷新
    • 字元分類與控制碼處理邏輯 (保留/捨棄/轉換)
    • Tab 位置計算的整除/餘數應用
    • 模組化程式結構:各功能獨立 PROC、參數透過全域變數/堆疊傳遞
    • 使用者體驗細節:簽名顯示、錯誤訊息分類、進度回饋

    總結

    CLEAN.ASM 是 DOS 時代實用工具程式的典範:功能明確、結構清晰、錯誤處理完善、緩衝區管理高效、使用者介面友善。其核心演算法 (字元過濾管線、Tab 展開、區塊 I/O) 在現代文字處理、編輯器、編譯器前端、日誌清洗工具中依然是基礎建構塊。研讀此碼,可深入理解「資料流處理」的本質邏輯,跨越時代與平台。

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