彙編語言-運行程序
彙編語言-一個程序
程序從寫出到執行
源程序
這是一段簡單的彙編源程序代碼,在彙編語言源程序中,包含兩種指令,種是彙編指令,種是偽指令。彙編指令是有對應的機器碼的指令,可以被編譯為機器指令,最終為CPU所執行。而偽指令沒有對應的機器指令,最終不被CPU所執行。那麼誰來執行偽指令呢?偽指令是由編譯器來執行的指令,編譯器根據偽指令來進行相關的編譯工作。
assume cs:codesg
codesg segment
mov ax,0123H
mov bx,0456H
add ax,bx
add ax,ax
mov ax,4c00H
int 21H
codesg ends
end
如上面顯示的代碼,codesg segment和codesg ends是一組成對使用的偽指令,他們定義了一個段codesg,分別對應着段的開始和結束。一個彙編程序是由多個段組成的,這些段被用來存放代碼、數據或當作棧空間。
end是一個彙編程序的結束標記,編譯器在編譯彙編程序的過程中,如果碰到了偽指令end,就結束對源程序的編譯。所以,在我們寫程序的時候,如果程序寫完了,要在結尾處加上偽指令end。否則,編譯器在編譯程序時,無法知道程序在何處結束。
assume這條偽指令的含義為假設」。它假設某一段寄存器和程序中的某一個用segment…ends定義的段相關聯。通過assume說明這種關聯,在需要的情況下,編譯程序可以將段寄存器和某一個具體的段相聯繫。
通過指令彙編指令mov ax,4c00H 和int 21H,實現程序的返回功能,以8086CPU為例,開機後運行的command控制台,當程序運行時將控制權交與程序,程序運行結束後,又將控制權返回給控制台。關於上面的兩條指令是如何實現將控制權返還給控制台,會在之後的章節詳細介紹。
編譯和鏈接源程序
當我們寫好一個程序後,將其保存為file.asm 文件,通過masm編譯器實現編譯功能,編譯器會根據代碼編譯出.obj 文件,之後再進行鏈接操作,使用命令link file.obj,即可實現鏈接功能生成.exe文件。
現在已是2021年,想要重新實現8086CPU不太現實的事情,這裡提供幾個可以代替的方法:
- emu8086
- DOSbox
對於第1種方法,他本身集成,無需控制指令,有完整的圖形化界面。
對於第2種方法它是一個仿 DOS界面,具體操作可以轉到enter link description here
執行程序
以dosbox如果只想執行程序,在鏈接出.exe文件後,直接輸入文件名即可(無需exe後綴)。若想debug程序,需要debug file.exe(文件全名)。
在命令控制台去執行程序,首先它會將我們的目標程序從可執行文件加載到內存中,將CPU的控制權交給目標程序,該程序才可運行。程序運行結束後,又將控制權返還給當初使它運行的程序。
debug程序
如果我們運行一個程序,需要一個程序去調用另一個程序,並將控制權交給他,直到程序運行結束將控制全返還。很容易想到,若是在debug程序的過程中,控制前在程序手中,我們是無法控制程序的操作命令的,在debug的過程中,雖然我們在執行程序,但控制權仍然在command中。
debug後,可以看到,Debug將程序從可執行文件加載入內存後,cx中存放的是程序的長度。hello.exe中程序的機器碼共有15個位元組。則hello.exe加載後,cx中的內容為000FH。現在程序已從hello.exe中裝入內存,接下來查看一下它的內容,可是我們查看哪裡的內容呢?程序被裝入內存的什麼地方?我們如何得知?這裡,需要講解一下在DOS系統中EXE文件中的程序的加載過程。
那麼,我們的程序被裝入內存的什麼地方?我們如何得知?
(1)程序加載後,ds中存放着程序所在內存區的段地址,這個內存區的偏移地址為0,則程序所在的內存區的地址為ds:0;
(2)這個內存區的前256個位元組中存放的是PSP,DOS用來和程序進行通信。從256位元組處向後的空間存放的是程序。
所以,從ds中可以得到PSP的段地址SA,PSP的偏移地址為0,則物理地址為SA x 16+0。
因為PSP佔256(100H)位元組,所以程序的物理地址是:SA x 16+0+256,可用段地址和偏移地址表示為:SA+10H:0。
INT21執行後,顯示出”Programterminatednormally”,返回到Debug中。表示程序正常結束。(注意,要使用P命令執行INT21。需要注意的是,在DOS中運行程序時,是command將程序加載入內存,所以程序運行結束後返回到command中,而在這裡是Debug將程序加載入內存,所以程序運行結束後要返回到Debug中。)
使用Q命令退出Debug,將返回到command中,因為Debug是由command加載運行的。在DOS中用”debug hello.exe”運行Debug對hello.exe進行跟蹤時,程序加載的順序是:command加載Debug,Debug加載hello.exe。返回的順序是:從hello.exe中的程序返回到Debug,從Debug返回到command。