實驗1 用機器指令和匯編指令編程
一、實驗目的
1. 熟練掌握使用debug工具編寫和調試x86匯編命令的方法
2. 掌握8086CPU、寄存器、內存的基礎知識
3. 理解并掌握內存中多字節數據的存放:小端法
4. 理解并掌握「棧」內存空間的特性和使用
5. 掌握指令mov, add, sub, jmp, push, pop的基礎用法
二、實驗內容
1. 教材實驗1(P35)
2. 教材實驗2(P71)
注意,為了便于驗證實驗結果,對「2. 實驗任務」的(1)做如下兩點調整:
① 在使用 a 命令輸入指令調試之前,先使用 e 命令將內存單元 0022:0~0022:7連續 8 個字節數據
修改為 50H, 51H, 52H, 53H, 54H, 55H, 56H, 57H
② 將 P74 實驗任務(1)中第1行的 mov ax, ffff → 改為 mov ax, 0022
三、實驗過程以及結論
1. 教材實驗1結論
實驗任務(1):使用Debug,用 e 命令和 a 命令兩種方式將下面的程序段寫入內存,逐條執行,觀察每條指令執行后CPU中相關寄存器中內容的變化。
機器碼 匯編指令
b8 20 4e mov ax, 4E20
05 16 14 add ax, 1416
bb 00 20 mov ax, 2000
01 d8 add ax, bx
① 使用 e 命令寫入機器碼,并用 t 命令單步執行,效果如下:

② 使用 a 命令寫入匯編指令,并用 t 命令單步執行,執行效果如下:

實驗任務(2):將下面三條指令寫入從2000 : 0 開始的內存單元中,利用這三條指令計算 2 的 8 次方。
mov ax, 1
add ax, ax
jmp 2000 : 2003
使用 a 命令寫入匯編指令并且使用 t 命令單步調試實驗結果如下圖所示:



實驗任務(3):PC機主板上的 ROM 中寫有一個生產日期,在內存 FFF00H~FFFFFH 的某幾個單元中,請找到這個生產日期并試圖改變它。
使用 d 命令查看 FFF00H~FFFFFH 單元的數據,檢查是否有生產日期,實驗截圖如下所示:

從上圖可以看出ROM 的生產日期為 1992 年 1 月 1 日。
當試圖改變地址是 FFF0:00F5 至 FFF0:00FC 的內存單元數據時,程序雖然不會報錯,但是會發現數據并未被寫入,具體內容如下圖所示:

以上圖情況來看,我們使用了 e 命令去改寫地址 FFF0:00F5 至 FFF0:00FC 內存單元的數據,之后使用 d 命令查看改寫的內容。
從中,我們可以得出改寫的命令并未執行成功。究其原因,地址為 FFF0:00F5 ~ FFF0:00FC 的內存單元對于 8086 CPU而言其實是
屬于 ROM 所映射的部分地址,凡是向只讀存儲器(ROM)的內存單元中寫入數據的操作都是無效的,因為這等于改寫只讀存儲
器的內容,這種操作是不被允許的,即使使用了 debug 命令修改其內存單元也會被視為無效指令。
實驗任務(4):向內存從 B8100H 開始的單元中填寫數據,如: -e B810:0000 01 01 02 02 03 03 04 04

實驗結果如上圖所示,可以發現屏幕上出現了幾個特殊的字符,而且還帶有顏色。其會出現的原因是由于我們向內存空間始址為
B810:0000 的內存單元連續寫入了 8 字節的數據,對于 8086CPU 而言,內存地址為 A000:0000 ~ BFFF:000F 會被映射成顯存
地址的范圍,向地址范圍是A000:0000 ~ BFFF:000F 的內存單元寫入數據,就是向顯存中寫入數據,而這些數據會被顯示卡輸出
到顯示器上,這正是在顯示屏會顯示輸出特殊字符的原因所在。
2. 教材實驗2結論
實驗任務(1) :使用 Debug,將下面的程序段寫入內存,逐條執行,根據指令執行后的實際運行情況填空。
mov ax, 0022
mov ds, ax
mov ax, 2200
mov ss, ax
mov sp, 0100
mov ax, [0]
add ax, [2]
mov bx, [4]
add bx, [6]
push ax
push bx
pop ax
pop bx
push [4]
push [6]
① 使用 e 命令修改內存單元0022:0~0022:f 中的數據:50 51 52 53 54 55 56 57,修改完使用 d 命令查看是否正確寫入,命令
執行結果如下圖所示:

② 使用 a 命令將上述匯編指令寫入內存單元中,并且使用反匯編 u 命令來查看指令是否被正確寫入,實驗過程如下圖所示:

③ 使用 t 命令,單步調試每一行匯編指令,實驗結果如下圖所示:


④ 理論分析結果與實驗結果一致,理論分析的過程如下圖所示:

實驗任務(2):仔細觀察 3.19 中的實驗過程,然后分析:為什么 2000: 0 ~ 2000: f 的內容會發生改變?
① 使用 a 命令輸入圖 3.19 所示 7 條匯編指令,使用 e 命令修改 2000:0~2000:f 的值,以及確認是否修改成功,實驗過程如下圖所示:

② 使用 t 命令單步調試每一條匯編指令,同時使用 d 命令查看每一步指令執行內存空間 2000:0~2000:f 所變化的值,實驗過程如下圖所示:

以文字方式陳述:
① 前3行匯編指令的功能,特別是,mov sp, 10意味著什么?初始時棧頂和棧底分別是?
mov ax, 2000 ; 將數據 2000H 寫入到 ax 寄存器當中 mov ss, ax ; 將 ax 中的數據寫入到棧段寄存器(ss)當中,即間接將數據 2000H 寫入到 ss 寄存器當中去 mov sp, 10 ; 將數據 10 H 寫入到棧頂指針寄存器當中,即定義一個基址為 20000H 而棧長為 8 字的棧
mov sp, 10 ;意味著棧頂地址相對于棧基址的偏移量為 10 H
初始化棧頂的實際物理地址為:20010 H
初始化棧底的實際物理地址為:2000E H
② 基于單步調試觀察到的變化,給出你對此的思考及可能原因分析。
下圖的內存空間是僅對于出入棧的數據變化所畫的圖解:
但是在實驗驗證過程中,當Debug執行完 mov sp, 10 這條匯編指令的時候,此時使用 d 命令發現棧中存有數據,而之前使用 e 命令
寫入的數據居然被覆蓋了,但是仔細觀察后,發現此時棧中存放的數據全部都是 8086CPU 中某些寄存器的值,從圖中可以發現棧中存
有CS、IP、BP、AX等寄存器的值了,這說明這是設計者有意為之,考慮到棧中每一次執行指令的時候,Dos 將相關數據存儲在棧中的
數據都必會有CS、IP這兩個寄存器的值,而凡是被這兩個寄存器所指向的內存單元都被認為是指令,同時棧中還存有先前 AX 寄存器的
值。由此可以推斷 DOS 系統中只有一個棧,并且系統會用該棧暫存相關數據,以便執行下一條指令,而此實驗中正好改變了系統中
SS、SP 的值,由此可見系統Debug單步調試的 t 命令執行匯編指令所需的數據全部都存放在棧當中。
浙公網安備 33010602011771號