- 編寫彙編源程序
- 對源程序進行編譯連接
1.使用 彙編語言編譯程序對源程序文件中的源程序進行編譯,產生目標文件。
2.用連接程序對目標文件進行鏈接,生成可在操做系統中直接運行的可執行文件。
其中,可執行文件包含兩部份內容:shell
- 程序(從源程序中的彙編指令翻譯過來的機器碼)和數據(源程序中定義的數據)
- 相關的描述信息(好比,程序有多大、要佔用多少內存空間)。
- 執行可執行文件中的內容
操做系統按照可執行文件中的描述信息,將可執行文件中的機器碼和數據加載入內存,並進行相關的初始化(好比設置CS:IP指向第一條要執行的指令),而後由CPU執行程序。
彙編語言中包含兩種指令:編程
- ** 彙編指令**
有對應的機器碼的指令,能夠被編譯爲機器指令,最終爲CPU所執行。- 僞指令:
沒有對應的機器指令,最終不被CPU所執行。
僞指令是由編譯器來執行的指令,編譯器根據僞指令來進行相關的編譯工做。
assume cs:codesg codes segment start: mov ax,0123H mov bx,0456H add ax,bx add ax, ax mov ax,4c00H int 21H codes ends end
segment和ends是成對使用的僞指令。segment說明一個段開始,ends說明一個段結束。
一個段必須有一個名稱來標識,使用格式爲:windows段名 segment …… 段名 ends
一個彙編程序是由多個段組成的,這些段被用來存放代碼、數據或當作棧空間來使用。
一個源程序中全部將被計算機所處理的信息:指令、數據、棧,被劃分到了不一樣的段中。
一個有意義的彙編程序中至少要有一個段,這個段用來存放代碼。操作系統
end是一個彙編程序結束的標誌,編譯器在編譯彙編程序的過程當中,若是碰到了僞指令end,就結束對源程序的編譯。
注意:
不要搞混了end和ends。ends是和segment成對使用的,標記一個段的結束。
end的做用是標記整個程序的結束。翻譯
assume
將有特定用途的段和相關的段寄存器關聯起來便可。
好比,上面的程序中:在程序的開頭,用assume cs:codesg將用做代碼段的codesg和CPU中的段寄存器CS關聯起來。debug
咱們將源程序文件中的全部內容稱爲源程序,將源程序中最終由計算機執行、處理的指令或數據,稱爲程序。
程序最早以彙編指令的形式存在源程序中,經編譯、鏈接後轉變爲機器碼,存儲在可執行文件中。
code
彙編源程序中,除了彙編指令和僞指令外,還有一些標號,好比「codesg」。
一個標號指代了一個地址。好比codesg和segment的前面,做爲一個段的名稱,這個段的名稱最終將被編譯、鏈接程序處理爲一個段的段地址。內存
源程序是由一些段構成的。咱們能夠在這些段中存放代碼、數據、或將某個段當作棧空間。編譯器
咱們的程序最早以彙編指令的形式存儲在源程序中,經編譯、鏈接後變爲機器碼,存儲在可執行文件中,那麼它怎樣獲得運行呢?
下面,咱們在一個單任務操做系統的基礎上,簡單的討論一下這個問題:編譯
一個程序P2在可執行文件中,則必須有一個正在運行的程序P1,將P2從可執行文件中加載入內存後,將CPU的控制權交給P2,P2才得以運行。
P2開始運行後,P1暫停運行。
當P2運行完畢後,應該將CPU的控制權交還給使它得以運行的程序P1,此後,P1繼續運行。
一個程序結束後,將CPU的控制權交還給使它得以運行的程序,咱們稱這個過程爲:程序返回。那麼,如何返回呢?應該在程序的末尾添加返回的程序段。
前面的程序中,下面兩條指令實現的功能就是程序返回:
mov ax,4c00H int 21H
程序在編譯時被編譯器發現的錯誤是語法錯誤。
源程序編譯後,在運行時發生的錯誤是邏輯錯誤。
在編譯的過程當中,咱們提供了一個輸入,即源程序文件。最多能夠獲得3個輸出:目標文件(.obj)、列表文件(.lst)、交叉引用文件(.crf)。
其中,目標文件是咱們最終要獲得的文件。
鏈接的做用有如下幾個:
- 當源程序很大時,能夠將它分爲多個源程序文件來編譯,每一個源程序編譯成爲目標文件後,再用鏈接程序將它們鏈接到一塊兒,生成一個可執行文件;
- 程序中調用了某個庫文件中的子程序,須要將這個庫文件和該程序生成的目標文件鏈接到一塊兒,生成一個可執行文件;
- 一個源程序編譯後,獲得了存有機器碼的目標文件,目標文件中的有些內容還不能直接用來生成可執行文件,鏈接程序將這些內容處理爲最終的可執行信息。因此,在只有一個源程序文件,而又不須要調用某個庫中的子程序的狀況下,也必須用鏈接程序對目標文件進行處理,生成可執行文件。
操做系統的外殼
操做系統是由多個功能模塊組成的龐大、複雜的軟件系統。任何通用的操做系統,都要提供一個稱爲shell(外殼)的程序,用戶(操做人員)使用這個程序來操做計算機系統進行工做。
DOS中有一個程序command.com,這個程序在DOS中稱爲命令解釋器,也就是DOS系統的shell。
DOS啓動時,先完成其餘重要的初始化工做,而後運行command.com,command.com運行後,執行完其餘的相關任務後,在屏幕顯示出由當前盤符合當前路徑組成的提示符,好比:「C:\」 或「C:\windows」等,而後等待用戶輸入。
用戶能夠輸入所要執行的命令,好比:cd、dir、type等,這些命令由command執行,command執行完這些命令後,再次顯示由當前盤符合當前路徑組成的提示符,等待用戶的輸入。
若是用戶要執行一個程序,則輸入該程序的可執行文件的名稱,command首先根據文件名找到可執行文件,而後將這個可執行文件中的程序加載入內存,設置CS:IP指向程序的入口。此後,command暫停運行,CPU運行程序。
程序運行結束後,返回到command中,command再次顯示由當前盤符和當前路徑組成的提示符,等待用戶的輸入。
在DOS中,command處理咱們的各類輸入:命令或要執行的程序的文件名。咱們就是經過commanf來進行工做的。
debug能夠將程序加載入內存,設置CS:IP指向程序的入口,但debug並不放棄對CPU的控制。 這樣,咱們可使用debug的相關命令來單步執行程序,查看每一條指令的執行結果。