EXECSUB 是一個用於 Microsoft 編譯版 BASIC(QuickBASIC/QB)調用外部程序的組合語言子程序。它允許 BASIC 程序通過 CALL EXECSUB(PROG$, PARM$, FCB1$, FCB2$, RETCD%) 方式加載並執行另一個可執行文件(如 COMMAND.COM 或其他 .EXE/.COM),並支持傳遞命令行參數、兩個 FCB(文件控制塊)以及獲取返回碼。該代碼展示了 DOS 2.0+ 環境下 INT 21h/4Bh(加載並執行)的完整封裝過程,包括中斷向量保存/恢復、內存縮減、參數塊構建、棧切換等關鍵步驟。
BASIC 運行時會佔用 INT 1Bh (Ctrl-Break)、INT 1Ch (Timer Tick)、INT 24h (Critical Error) 等中斷。執行子程序前必須將這些向量保存,並恢復 BASIC 的影子向量(B1BIP/B1BCS 等),否則子程序運行期間 BASIC 的中斷處理會失效。代碼通過 CLI/STI 關中斷/開中斷保護操作原子性。
INT 21h/4Ah)獲取 PSP 段地址(ES:[0002h] 存儲段落數),計算當前程序佔用內存,釋放多餘內存給子程序使用。若失敗返回錯誤碼 0。
EXEC 參數結構)prm1:環境段地址(0 表示繼承父進程環境)prm2:命令行指針(DS:DX 指向參數字符串,以 0Dh 結尾)prm3/prm4:兩個默認 FCB 指針(DS:SI 格式)代碼從 BASIC 字符串描述符(skip=2 跳過長度字)提取偏移/段地址填入參數塊。
保存當前 SS:SP 到 stak,調用 INT 21h/4Bh AL=0 加載並執行。子程序結束後恢復棧、恢復中斷向量、恢復 BASIC 的 DS,最後將返回碼寫入 RETCD%。
; EXECSUB - execute program from compiled BASIC - requires DOS 2.00
; CALL EXECSUB(PROG$,PARM$,FCB1$,FCB2$,RETCD%)
cseg segment para public 'code'
public execsub
execsub proc far
assume cs:cseg,ds:cseg,ss:nothing,es:nothing
basicds equ 510h ; BASIC 數據段地址(在 PSP:510h)
i24ip equ 90h ; INT 24h 向量偏移
i24cs equ 92h
i1bip equ 6ch ; INT 1Bh 向量
i1bcs equ 6eh
i1cip equ 70h ; INT 1Ch 向量
i1ccs equ 72h
b24ip equ 51ah ; BASIC 影子向量
b24cs equ 51ch
b1bip equ 516h
b1bcs equ 518h
b1cip equ 512h
b1ccs equ 514h
; ... 保存向量、縮減內存、構建參數塊、棧切換、執行、恢復現場 ...
execsub endp
cseg ends
end
該代碼是早期混合語言編程(BASIC + ASM)的典型樣本,展示了:
雖然現代系統不再使用 DOS 實模式,但「保存上下文 → 準備參數 → 調用執行器 → 恢復上下文」的模式在作業系統內核、虛擬機監控器、沙箱隔離等領域依然普遍存在。