彙編語言-運行程式
彙編語言-一個程式
程式從寫出到執行
源程式
這是一段簡單的彙編源程式程式碼,在彙編語言源程式中,包含兩種指令,種是彙編指令,種是偽指令。彙編指令是有對應的機器碼的指令,可以被編譯為機器指令,最終為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。