序
制定一個MS-DOS應用程序計劃需要認真分析程序的大小。這種分析可以幫助程序員確定MS-DOS支持的兩種程序風格中哪一種最適合該應用程序。.EXE程序結構為大型程序提供了好處,因為所有.EXE文件之前都有額外的512字節(或更多)的文件頭。另一方面,以失去這些額外好處為代價,.COM程序結構不會使小型程序負擔這些額外文件頭字節的開銷。因為.COM程序在被EXE2BIN轉換之前一開始就是.EXE程序,并且在MS-DOS下應用程序編程的幾個方面在使用的程序結構不同的情況下仍然相似,因此對于準備編寫只有.COM程序的程序員來說,對.EXE結構的充分了解也是有益的。因此,我們將從討論.EXE程序的結構和行為開始,然后看一下.COM程序和.EXE程序之間的區別,包括.COM程序結構和內容的限制。
exe程序
.EXE程序相比于.COM程序在應用程序設計方面有幾個優勢。
選擇.EXE格式的考慮因素包括:
- 非常大的程序
- 多個段 覆蓋區
- 段和遠地址常量 長跳轉
- 將程序升級到MS OS/2保護模式的可能性
.EXE格式的主要優勢是由文件頭提供的。最重要的是,文件頭包含了使程序能夠進行直接段地址引用的信息—這是程序要超出64KB以上才能滿足的要求。
文件頭還告訴MS-DOS程序需要多少內存。這些信息可以防止系統分配給程序不需要的內存—這在未來升級程序以有效運行在MS OS/2保護模式下的情況下是很重要的考慮因素。
在詳細討論.EXE程序結構之前,我們將看一下.EXE程序的行為。
截取自早期的微軟檔案
這張圖片展示了一個.EXE程序在內存中的示例,當MS-DOS首次交給程序控制時。該圖顯示了微軟首選的程序段排列方式。
在將控制權轉移到.EXE程序之前,MS-DOS會初始化內存的各個區域以及微處理器的幾個寄存器。以下討論解釋了在將控制權交給.EXE程序之前可以從MS-DOS期待的內容。
程序段標志psp
程序段標志(或者我也叫他前綴)(PSP)不是任何程序代碼的直接結果。相反,這個特殊的256字節(16段)內存頁是由MS-DOS在加載所有.EXE和.COM程序到內存時,在它們前面構建的。雖然PSP確實包含對新程序有用的幾個字段,但它主要作為CP/M的遺留物存在 - 微軟采用了PSP以便更輕松地將在CP/M環境下可用的大量程序移植到MS-DOS環境中。圖4-2顯示了組成PSP的字段。
PSP:0000H([舊熱啟動])PSP以8086系列INT 20H指令開始,程序可以使用該指令將控制權傳回MS-DOS。PSP在偏移00H處包含此指令,因為在CP/M下,這個地址是WBOOT(熱啟動/終止),而CP/M程序通常通過跳轉到該中斷來終止。這種終止方法不應在新程序中使用。請參見下面的終止.EXE程序。
PSP:0002H(分配給程序的最后一個段的地址)MS-DOS在PSP的偏移02H引入了一個字。它包含已分配給程序的內存塊后的段地址。這個地址應該僅用于確定分配給程序的內存塊的大小或結束位置;它不應被視為程序可以占用的自由內存的指針。在大多數情況下,這個地址不會指向空閑內存,因為任何空閑內存都已經被分配。
這張圖片是微軟msdos4時期的
除非使用/CPARMAXALLOC開關鏈接程序,否則程序不會被分配到指定的內存。即使使用了/CPARMAXALLOC,MS-DOS可能會將程序安裝到與程序需求一樣大的內存塊中。行為正常的程序應該只通過提供的MS-DOS功能調用來獲取額外的內存。PSP:0005H(MS-DOS功能調用[舊bios中斷)偏移05H也是從CP/M中遺傳下來的。這個位置包含一個8086系列的遠程(段間)調用指令,用于調用MS-DOS的功能請求處理程序。(在CP/M中,這個地址是操作系統中斷,用于類似的目的。)這個向量不應該在新程序中用于調用MS-DOS。MS-DOS僅提供這個中斷以支持CP/M風格的程序,因此只能通過它支持CP/M風格的功能(00-24H)。
PS13:000AH-0015H(22H、231I和24H中斷向量保留)MS-DOS使用偏移OAH到15H來保存三個特定程序的中斷的內容。MS-DOS必須保存這些,因為它允許任何程序通過一個MS-DOS功能調用執行另一個程序(稱為子進程),當被調用的程序終止時返回控制給原始程序。因為當子程序終止時原始程序會恢復執行,所以MS-DOS必須為原始程序還原這三個中斷,以防被調用的程序改變了它們。涉及的三個向量包括程序終止處理程序(中斷22H)、Control-C/Control-Break處理程序(中斷23H)和關鍵錯誤處理程序(中斷2411)。MS-DOS將這些的原始執行內容保存在子程序的PSI’中,從偏移0A開始為程序結束處理程序、OM為Control-C/Control-Break處理程序,12H為關鍵錯誤處理程序。
PSP:002C1-1(環境段地址)在MS-DOS 2.0及更高版本中,偏移2CH處的字包含了程序所能找到的PSP中最有用的一部分信息——MS-DOS環境的第一個段地址。這個指針使程序能夠通過環境搜索任意由用戶使用SET命令放置在那里的配置或目錄搜索路徑字符串.
PSP008011默認的 DTA 位于 PSP 的整個后半部分(128 字節)。MS-DOS 將內存中的這一區域用作程序使用 FCB 風格文件訪問函數時的默認記錄緩沖區。再次,MS-DOS 是從 CP/M 繼承了這個位置。(MS-DOS 提供一個程序可調用以更改 MS-DOS 將用作當前 DTA 的地址的功能。請參閱微軟的參考之南《系統調用:中斷 211:函數 1ah》。)因為默認 DTA 在程序執行需要它的文件操作之前沒有任何作用,所以 MS-DOS 將命令尾置于此供程序檢查。命令尾包括用戶執行程序時在程序名稱之后輸入的任何文本。通常,ASCII 空格(20H)是命令尾中的第一個字符,但 MS-DOS 認識的任何分隔符都可以占據此位置。MS-DOS 從偏移量 81H 開始存儲命令尾文本,并始終在文本末尾放置一個 ASCII 回車(ODH)。為了提供額外幫助,它在偏移量 80H 處放置了命令尾的長度。這個長度包括最后的 ODH 之外的所有字符。例如,命令行:
c:》DOIT ASS V CAN
然后你再doit對應psp:80h的地方就有
0A 20 41 53 53 20 56 20 43 41 4E 0c長度 空格 a s s 空格 v 空格 c a n 長度(去掉最后一個字節的) (總長度,含自身)
- 未完待續