有關CPU和存儲單元的概念在前一節我們已經了解,那么如何觀察實際機器內部的情況呢?能不能看到具體的寄存器、標志、存儲單元的內容呢?可不可以修改和控制它們呢?
DEBUG這個有力工具,就可以深入到機器內部進行觀察了。
調試工具DEBUG
在DOS操作系統和Windows操作系統中,都提供了調試工具DEBUG。DEBUG是為匯編語言設計的一種調試工具。
1. DEBUG的主要命令
DEBUG命令有20多個,我們主要學習最常用的命令。
- R ——查看和修改寄存器
- D ——查看內存單元
- E ——修改內存單元
- U ——反匯編,將機器指令變為匯編指令
- T /P——單步執行
- G ——連續執行程序
- A ——輸入匯編指令
- Q ——退出
2. 進入DOS
DEBUG要先進入DOS環境中再使用,linux虛擬環境中進入DOS的方法:
- 進入Linux的命令行終端
- 輸入
DOSemu進入DOS環境,DOSemu也有其他參數,可以輸入dosemu --help查看 - 退出DOS環境,在DOS中輸入命令
exitemu - 或者在桌面上雙擊dosemu圖標,直接進入DOS
基本的DOS命令:
- cd\ ——首先要用cd\ 退回到根目錄C>下
- dir ——顯示文件列表
- md hb ——建立hb子目錄
- cd hb ——進入hb子目錄
- copy d:\dos\masm.exe c:\hb ——將D盤dos目錄下的masm.exe拷貝到C盤hb目錄下
- copy d:\dos\link.exe c:\hb ——將D盤dos目錄下的link.exe拷貝到C盤hb目錄下
- cd .. ——退回到上一級目錄
- del \hb\masm.exe ——刪除hb子目錄中的某文件
- rd hb ——刪除hb子目錄(子目錄中的所有文件必須先刪除)
- e:——進入e盤
- cls ——清屏
- type——顯示文本文件內容(如type c:\hb\abc.asm)
DOS和DEBUG命令都支持大小寫。
3. 進入DEBUG
要觀察計算機內部的情況,可直接進入DEBUG。如果要調試及觀察可執行文件,則要在DEBUG后加上文件名和擴展名.EXE。我們先觀察,因此直接鍵入DEBUG進入系統,如圖所示。

DEBUG的提示符是小短線- ,在其后輸入命令。
1. R命令——查看和修改寄存器
R命令有兩種用法:直接鍵入R——將顯示CPU所有的寄存器和標志位;
修改寄存器——在R后跟寫寄存器名,回車后先顯示寄存器的內容,在冒號后鍵入新的值;再用R命令就可看到修改后的內容了。將AX寄存器的值改為1234H。

再來看四個段寄存器DS、ES、SS、CS的值都是07BE,說明現在系統處在同一個邏輯段中(不同的系統環境下,段寄存器的值可能不一樣)。操作系統根據內存的情況為各段分配段地址,因此每台機器或每次運行時段地址值可能會不一樣。
IP指令指針寄存器的值是0100H,表示將要執行的指令在代碼段的0100H單元中。該指令單元的邏輯地址應該由CS:IP構成,即0AFA:0100H。
我們來看在寄存器的下面那一行的表示。該行顯示的是代碼段的一條指令的反匯編。所謂反匯編,指的是將二進制的機器指令顯示成匯編指令。由三部分構成:最左邊07BE:0100表示該指令所在單元的邏輯地址,中間F60000表示該指令的機器碼,第3列顯示為匯編指令TEST。
2. D命令——查看內存單元
內存每16個字節單元為一小段,邏輯段必須從小段的首址開始。用D命令可以查看存儲單元的地址和內容。
D命令格式為:
D 段地址:起始偏移地址 [結尾偏移地址] [L范圍]
例如:
D DS:0 查看數據段,從0號單元開始 D ES:0 查看附加段,從0號單元開始 D DS:100 查看數據段,從100H號單元開始 D 0200:5 15 查看0200H段的5號單元到15H號單元(在虛擬機上該命令不能執行) D 0200:5 L 11 用L選擇范圍。查看0200H段的5號單元到15H號單元共10個單元

其中左邊一列為邏輯地址,中間部分為存儲單元的內容。每行為16個字節單元,中間的小橫線用於區分前8個單元和后8個單元。在邏輯地址中只給出每行第一個單元的偏移地址,其余15個單元的偏移地址沒有標出。可以推斷出圖中第一行單元的偏移地址從0000H到000FH,第二行單元的偏移地址為0010H~001FH,以此類推。右邊部分顯示出內存單元中的ASCII碼表示的字符,無法顯示時用小點代替。
如果在D后面直接寫出偏移地址,則顯示當前數據段下偏移地址開始的內存單元,如:
D 10 從數據段10H號單元開始顯示
D100 從數據段100H號單元開始顯示
注意:多次鍵入D,可連續顯示后面的單元內容。
3. E命令——修改內存單元
用E命令可以改寫多個存儲單元的內容。格式為:E 起始地址 修改值 修改值 …
例如:將數據段中的DS:3~DS:5 三個單元的內容修改為14、15、16。命令為
E DS:3 14 15 16
如果E后面直接跟偏移地址,則修改當前數據段下偏移地址所指單元值;還可以用E命令修改其它段的存儲單元內容。
E 10 修改當前數據段10H號單元內容 E ES:100 修改附加段100H號單元內容 D ES:100 查看一下100H單元的內容是否修改了
4. A 命令——輸入匯編指令
輸入匯編指令,系統自動地將鍵入的匯編指令翻譯成機器代碼,並相繼地存放在從指定地址開始的存儲區中。由於DEBUG下的數值默認為十六進制數,因此先要將十進制數轉換成十六進制數。
例如,前一節提到的計算Z=35+27的匯編指令為:
MOV AX,23H
ADD AX,1BH
MOV [0000],AX
輸入A命令后,系統自動地給出邏輯地址為0AEE:0100(CS:偏移地址),在其后輸入匯編指令,回車后可輸入下一條指令,直接回車則退出輸入。操作過程如下:

也可以在A命令后給出指令的存放地址,如A CS:0000,表示從代碼段的0號單元開始存放輸入的指令。
5. U命令 ——反匯編
程序員編寫的匯編語言源程序經過匯編(編譯)后生成了二進制的機器指令代碼,而U命令可將二進制的機器指令變為助記符形式的匯編指令,因此稱之為“反匯編”。
通過U命令,我們可以得到機器指令與匯編指令的對照,了解機器指令的存儲情況

第一列為邏輯地址,第二列為機器指令,第三列為匯編指令
注意:上圖顯示的程序代碼並不是用戶編寫的程序,因為在輸入DEBUG命令時沒有附加exe文件。這段程序代碼是系統代碼段中保存的內容,有可能是系統程序,也有可能是無效的代碼。
U后跟偏移地址,則從該地址開始反匯編。如:
U 0 從代碼段0號單元開始反匯編
U100 從代碼段100H號單元開始反匯編
注意:多次鍵入U,可連續顯示后面的程序部分。
6. T/P命令——單步執行
輸入完指令后,應該執行它。
T命令可以一條一條地執行指令,相當於逐過程調試。
P命令的作用與T命令相同,當遇到中斷指令INT n和調用指令CALL時,會進入子程序,相當於逐語句調試。
下面執行第四步中的匯編指令:
本次執行前,先用R命令查看指令指針寄存器IP的值是否為0100,如果不是,用R IP命令修改為0100。表示現在要從CS:0100單元開始執行指令。
T命令每執行一次,都會顯示當前寄存器的狀況,我們可以隨時了解指令的執行情況。

用D DS:0命令查看該單元的值已經為003B(兩個字節單元為一個字單元),這里類似大端法,高位在高地址,低位在低地址。

T命令還可以連續執行多條指令。如上例中連續執行3條指令,可用如下T命令:
-T 3
T命令也可以設置開始地址和執行條數。如上例中從0100H開始連續執行3條指令,可用如下T命令:
-T =0100 3
7. G命令——連續執行程序
8. Q命令 ——退出DEBUG
鍵入Q,回車后退出DEBUG,返回到DOS下。
