一、實驗結論:
1.實驗任務2:PC機主板上的ROM中有一個生產時期,在內存FFF00H ~ FFFFFH的某幾個單元中,請找到這個生產時
期,並試圖修改它
在debug中,使用d命令查看生產日期:
使用e命令嘗試修改(並查看修改后的結果):
發現該日期並未修改,因為此操作是修改只讀存儲器中的內容,是無法實現的,只讀存儲器在內存的地址為C0000~ FFFFFH。
2.實驗任務3:在debug中,使用e命令,向內存單元填寫數據
顯示如左上角
在debug中,使用f命令,向內存單元批量填寫數據,顯示在編輯器底部一行:
自己嘗試改變內存地址和存入的數據,結果如下(顯示出現在編輯器左側中部的位置):
3 .實驗任務4:已知內存單元00201H ~ 00207H分別存放數據(如下圖所示),00220H ~ 0022fH用作棧空間。
在debug環境中,按順序錄入以下內容,單步跟蹤調試,觀察寄存器和內存空間00200H~00207H,以
及,棧空間00220 ~ 0022fH內容變化情況。記錄實驗結果。回答問題,驗證和你的理論分析結果是否一
致。
(1)填空
-a mov ax, 20 mov ds, ax mov ss, ax mov sp, 30 push [0] ; 執行后,寄存器(sp) = __002E__ push [2] ; 執行后,寄存器(sp) = __002C__ push [4] ; 執行后,寄存器(sp) = __002A__ push [6] ; 執行后,寄存器(sp) = _0028___ pop [6] ; 執行后,寄存器(sp) = _002A___ pop [4] ; 執行后,寄存器(sp) = __002C__ pop [2] ; 執行后,寄存器(sp) = __002E__ pop [0] ; 執行后,寄存器(sp) = __0030__
(2)問題1:題目要求是把00220H ~ 0022fH用作棧空間。指令 mov ss, ax 和 mov sp, 30 執行后,棧頂的邏輯地址和物理地址分別是?
sp邏輯地址:0030
物理地址:0022fH
(3)問題2:單步調試到匯編指令 push [6] 執行結束, pop [6] 執行之前,使用 d 20:20 2f 查看此時棧空間數據,給出實驗截圖。
(4)問題3:匯編指令 pop [0] 執行結束后, pop [0] 指令執行結束后,使用d命令 d 20:0 7 查看此
時數據空間內的數據是否有變化。給出實驗截圖。
(5)問題4:如果把最后四條指令改成截圖中的順序, pop [6] 指令執行結束后,使用d命令 d 20:0 7
查看此時數據空間內的數據是否有變化。給出實驗截圖
4.實驗任務5:在debug環境中,實踐以下內容:
(1)問題1:使用t命令單步執行 mov ss, ax 時,是單步執行完這一條指令就暫停了嗎?后面的指令 mov sp, 30 是什么時候執行的?
觀察debug操作,發現單步執行mov ss, ax后,mov sp, 30就執行了,可以看到sp已經等於0030了。
(2)問題2:根據匯編指令,前三條指令執行后,00220H ~ 0022fH被設置為棧空間。並且,初始時,已通過f命令將初始棧空間全部填充為0。觀察單步調試時,棧空間00220H ~ 0022fH內存單元值的變化,特
別是圖示中黃色下划線表示出的數據值(073F:0108)。根據實驗觀察,嘗試思考和分析原因。
我繼續往下運行下去,再查看-d 20:20 2f
出現以下改變:
則可推出,棧空間內內存單元可以存儲下一條指令的位置,即CS和IP寄存器的值。
5.實驗任務6:使用任何一款文本編輯器,編寫8086匯編程序源碼
assume cs:code code segment start: mov cx, 10 mov dl, '0' s: mov ah, 2 int 21h add dl, 1 loop s mov ah, 4ch int 21h code ends end start
使用masm、link,匯編、鏈接,得到可執行文件task5.exe。運行程序。結合程序運行結果,理解程序
功能。
masm、link命令在前(沒有截到)
使用debug工具,調試task5.exe。根據第4章所學知識,任何可執行程序在執行時,都有一個引導程序
負責將其加載到內存,並將CPU控制權移交給它,也即將CS:IP指向可執行程序中第一條機器指令。在加
載可執行程序時,可執行前面512字節是程序段前綴PSP(Program Segment Prefix),用於記錄程序一些
相關信息。
在debug中,使用d命令,查看task5.exe的程序段前綴,觀察這256個字節的內容,驗證前兩個字節是
否是CD 20。
查看程序段前綴,前兩個字節是CD 20:
6.實驗任務7:下面程序的功能是,完成自身代碼的自我復制:把 mov ax, 4c00h 之前的指令復制到內存0:200開始的連續的內存單元。補全程序,並在debug中調試驗證,確認是否正確實現了復制要求。
assume cs:code code segment mov ax, _____ mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, _____ s: mov al, [bx] mov es:[bx], al inc bx loop s mov ax, 4c00h int 21h code ends end
可知是要將一定的代碼段內容填入指定內存單元,ex(0020h):[bx]作為目標地址,則代碼段地址作為源地址,我把第一個空填 cs;
先隨便填一個cx,我先填0001h,在debug用u命令查看, mov ax, 4c00h指令停留在0017h,我有些不確定,決定嘗試0015和0017;
0015h並沒有在目的地址存儲完整的代碼,
0017則完整拷貝了,
最后補全后的代碼為:
assume cs:code code segment mov ax, cs mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, 0017h s: mov al, [bx] mov es:[bx], al inc bx loop s mov ax, 4c00h int 21h code ends end
二、實驗總結
1、字節是固定的單位,等於八個二進制位,而字是計算機進行數據處理和運算的單位,用字長來表示大小,字長為若干個字節,不同的機器字長可能不同,在8086CPU中字長為16位,即兩個字節,8086的幾個數據寄存器是16位寄存器,每一個 16 位寄存器就可以當做 2 個獨立的 8 位寄存器來使用了,所以在8086系統中,既可以將一個字存入寄存器內,也可以將字節存入,而且可以指定實在16進制的高二位還是第二位,在顯示的時候,而在機器讀取的時候從低位開始讀,字的地址是低位的地址,我總是忘記,導致操作就不熟練甚至出現錯誤。