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

DOS 時代組合語言原始碼賞析:_charop 字元操作函數 (Lattice C 庫)

     編輯:組合語言

前言

本文收錄 Lattice C 編譯器 DOS 函數庫中的 _charop 組合語言實作。該函數封裝 DOS 2.0 INT 21h AH=55h 服務,用於取得/設定開關字元 (SwitChar) 以及查詢/設定裝置可用性。雖極簡短,卻完美示範了組合語言實作 C 庫函數的參數傳遞慣例、暫存器使用、中斷呼叫封裝。

函數原型與功能

int _charop(int al, int dl);  // C 宣告

; 功能對應:
; al=0, dl=0 : 取得開關字元 (預設 '/')
; al=1, dl=字元 : 設定開關字元
; al=2, dl=0 : 取得裝置可用性位圖
; al=3, dl=值 : 設定裝置可用性

完整原始碼

title MSDOS 2.00 Function Library for Lattice C
subttl -
;;
;;FUNCTION: Sets and returns switch character and device availability.
;;
;;CALL:
;; ret= _charop(al,dl)
;; int ret; DL return value,
;; int al; charoper function
;; int dl; charoper data
;;
;;RETURN: See the DOS docs for details.
;; _charop(0,0) returns the ASCII switch char,
;; _charop(1,'-') sets the switch to -,
;; _charop(2,0) returns device availability,
;; _charop(3,i) sets device availability.
;;
;;LONG 32 bits (4 bytes)
;;INT 16 bits (2 bytes)
;;CHAR 8 bits (1 byte
;;
page
pgroup group prog
prog segment byte public 'prog'
assume cs:pgroup,ds:pgroup
public _charop
_charop proc near
 push bp
 mov bp,sp
 mov al,[bp+4]      ; 取得第一參數 al (函數代碼)
 mov dl,[bp+6]      ; 取得第二參數 dl (資料)
 mov ah,55          ; DOS 2.0 功能 55h - 字元操作
 int 33             ; INT 21h (33 decimal = 21h)
 mov al,dl          ; 返回值在 DL,移至 AL
 mov ah,0           ; 擴展為 16 位整數返回
 pop bp
 ret
_charop endp
prog ends
end

技術細節解析

1. C 呼叫慣例 (Small Model, Near Call)

  • 參數從右至左壓堆疊:呼叫端 push dl; push al (或對應寬度)。
  • 被呼叫端:BP 指向堆疊幀,[BP+4] 為第一參數 al,[BP+6] 為第二參數 dl (因 IP 佔 2 位元組,BP 佔 2 位元組)。
  • 返回值放在 AX (16 位整數)。
  • BP, DS, SS, SI, DI 需保存 (此處僅用 BP),AX, BX, CX, DX, ES 可自由使用。

2. DOS INT 21h AH=55h 服務

此服務僅存在於 DOS 2.0+,早期版本不支援。

3. 組合語言實作要點

  • int 33 即 int 21h (3310 = 2116),MASM 支援十進位中斷號。
  • 輸入參數直接對應 AL/DL,無需額外轉換。
  • DOS 返回值在 DL,C 函數慣例返回在 AX,故 mov al, dl; mov ah, 0。
  • 極精簡:僅 11 條指令,無分支、無區域變數,展現組合語言封裝系統呼叫的高效率。

4. 記憶體模型與段定義

pgroup group prog
prog segment byte public 'prog'
assume cs:pgroup,ds:pgroup
  • byte 對齊 (段落對齊為 para)。
  • public 'prog' 類別名供連結器分組。
  • GROUP 將 prog 歸入 pgroup,小模型下 CS=DS=SS=pgroup。

歷史背景與現代對應

AL (子功能)輸入 DL輸出 DL說明
00h忽略當前開關字元取得 SwitChar (預設 2Fh '/')
01h新開關字元無設定 SwitChar
02h忽略裝置可用性位圖Bit 0=CON, 1=AUX, 2=PRN, 3=CLOCK$...
03h新位圖值無設定裝置可用性
DOS / Lattice C現代對應
開關字元 ('/' 或 '-')CLI 解析庫 (getopt, argparse, CLI11) 自動處理
裝置可用性位圖 (CON/AUX/PRN)裝置驅動程式模型、即插即用、SetupDi API
INT 21h 系統呼叫Win32 API / 系統呼叫 (syscall/sysenter)
Small Model 近呼叫慣例x64 快速呼叫慣例 (RCX,RDX,R8,R9...)
.OBJ 連結為 .LIB靜態庫 .lib / 動態連結 .dll / NuGet 套件

學習重點

  • 組合語言實作 C 可呼叫函數的堆疊幀建立 (push bp; mov bp,sp) 與參數存取
  • 暫存器保存規範:BP, SI, DI, DS, SS 非易失性,AX, BX, CX, DX, ES 易失性
  • 系統中斷服務的輸入/輸出暫存器約定
  • 返回值轉換:系統呼叫返回 DL → C 返回 AX
  • 極簡函數的完整結構:PROC/ENDP、PUBLIC、段組織

總結

_charop 雖僅 11 行指令,卻浓缩了組合語言介面 C 語言、封裝 DOS 系統服務、遵循呼叫慣例、暫存器管理、極致精簡的所有核心要素。它是早期 PC 時代編譯器運行庫開發的縮影,也是理解「系統程式設計」基礎的最佳切入點之一。

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