實驗結論
1.實驗任務2
①查看ROM生產日期,命令為:-d ffff:0 ff ,截圖如下:
可以看到生產日期在FFFF0~FFFFF這個地址中,日期為01/01/92。
②嘗試用e命令修改這個生產日期,截圖如下:
發現這個生產日期無法隨意修改,可以推斷出地址FFFF0~FFFFF的內存單元為只讀存儲器,寫入數據操作是無效的。
2.實驗任務3
①使用e命令,向內存單元填寫數據,命令為:-e b800:0 03 04 03 04 03 04 03 04 03 04 ,結果如下圖:
②使用f命令,向內存單元批量填寫數據,命令為:-f b800:0f00 0f9f 03 04 ,結果如下圖:
③對b800:0進行數據修改,命令為-e b800:0 03 03 03 03 03 03 03 03 03 03 ,結果如下圖:
發現內存數據修改成功,圖案由紅色變為藍色。
3.實驗任務4
在dos中輸入下面命令:
-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
問題1:題目要求是把00220H ~ 0022fH用作棧空間。指令 mov ss, ax 和 mov sp, 30 執行后, 棧頂的邏輯地址和物理地址分別是?
答:邏輯地址為:20:30H,物理地址為:00230H。
問題2:單步調試到匯編指令 push [6] 執行結束, pop [6] 執行之前,使用 d 20:20 2f 查看此 時棧空間數據,給出實驗截圖。
答:push [6] 執行結束, pop [6] 執行之前,使用 d 20:20 2f 查看此 時棧空間數據,截圖如下:
問題3:匯編指令 pop [0] 執行結束后, pop [0] 指令執行結束后,使用d命令 d 20:0 7 查看此 時數據空間內的數據是否有變化。給出實驗截圖。
答:pop [0] 指令執行結束后,使用d命令 d 20:0 7 查看此時數據空間內的數據,截圖如下:
可以發現數據空間內的數據沒有變化。
問題4:如果把最后四條指令改成截圖中的順序, pop [6] 指令執行結束后,使用d命令 d 20:0 7 查看此時數據空間內的數據是否有變化。給出實驗截圖。
答:把最后四條指令改成截圖中的順序, pop [6] 指令執行結束后,使用d命令 d 20:0 7 查看此時數據空間內的數據,截圖如下:
可以發現隨着最后出棧順序的不同,數據空間內的數據發生了變化。
4.實驗任務5
問題1:使用t命令單步執行 mov ss, ax 時,是單步執行完這一條指令就暫停了嗎?后面的指令 mov sp, 30 是什么時候執行的?
答:使用t命令單步執行 mov ss,ax 時,不是單步執行完這一條指令就暫停了。在用t命令執行 mov ss, ax 時,后面的下一條指令 mov sp, 30 緊跟着執行了。
從圖中可以看出,執行完 mov ss,ax后一條待執行的指令跳到了 mov ax,2021,而sp由00FD變成了0030,而能將sp設為30的指令只有mov sp,30,由此得到在用t命令執行 mov ss, ax 時,后面的下一條指令 mov sp, 30 緊跟着執行了。
問題2:根據匯編指令,前三條指令執行后,00220H ~ 0022fH被設置為棧空間。並且,初始時,已通 過f命令將初始棧空間全部填充為0。觀察單步調試時,棧空間00220H ~ 0022fH內存單元值的變化,特別是圖示中黃色下划線表示出的數據值。根據實驗觀察,嘗試思考和分析原因。
答:圖中的073F對應cs寄存器內的值,0180對應ip寄存器內的值,繼續執行接下來幾條指令可以發現同一現象。因此可以推斷出:棧空間內存單元值發生變化的原因是在用t指令執行命令時會產生中斷,cpu為了保護現場,會先將IP、CS兩個寄存器的值入棧。
5.實驗任務6
程序源碼為:
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 task6.asm; 對程序進行編譯,如下圖:
用命令 link task6.obj; 進行連接,如下圖:
運行task6.exe,如下圖:
由於psp存放於內存區的前256個字節中,所以進入debug模式后用命令 d 075a:0 ff 來查看psp中的內容,如下圖所示:
可以看到psp的前兩個字節正是CD 20。
6.實驗任務7
程序補全后代碼為:
assume cs:code code segment mov ax, cs mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, 17h s: mov al, [bx] mov es:[bx], al inc bx loop s mov ax, 4c00h int 21h code ends end
第一個空填cs,原因是題中要求復制 mov ax, 4c00h 之前的指令,也就是從代碼段開始到 mov ax, 4c00h 的所有指令,故將代碼段起始地址cs賦給數據段。
第二個空填17h,原因是要完成復制必須要確定要復制的指令的字節數,也即循環次數cx,於是只要數出待復制指令所占的字節數即可。為了得到指令字節數,我先隨便賦給cx一個值,然后編譯連接后在debug中用u命令顯示所有的命令,如下圖,接着便可以數出待復制指令的字節數,數出來是23個字節,轉換為16進制便是17h,因此將17h賦給cx。
對於第二個空我覺得也可以將這條指令改為 sub cx 5 ,因為cx也可以表示該程序的所有字節總數,故將cx減去不用被復制的指令的字節數就能得到需要被復制指令的字節數,不需要被復制的指令有mov ax,4c00h 和 int 21h ,占5個字節,所以應將cx-5,這樣就沒有必要一個個去數,更加簡單。
在debug中調試,使用g命令將程序執行到 loop s 之后、 mov ax, 4c00h 之前,用 u0:200 216 反匯編命令查看,發現已經成功復制指令,如下圖:
實驗結論
在這次實驗中,我對debug中各種基礎命令的使用有了進一步的認識和掌握,了解了內存空間的分配以及棧空間的分配和利用。
通過本次實驗,我還收獲了以下知識點:
(1)地址C0000~FFFFF的內存單元為只讀存儲器,寫入數據操作是無效的。
(2)地址A0000~BFFFF為顯存地址空間,向其中寫入數據,這些數據會被輸出帶顯示器上。
(3)棧底總是在地址較大的一側,每入棧一次,sp對應減去入棧的字節數,每出棧一次,sp對應加上出棧的字節數,出棧順序與入棧順序相反。
(4)程序存放的內存區域的前256個字節用作程序前綴(PSP),用作dos和程序的通信。
在調試程序的過程中,我也有了以下幾個發現:
(1)在用t指令執行命令時會產生中斷,cpu為了保護現場,會先將IP、CS兩個寄存器的值入棧。
(2)在執行了修改ss的mov指令后,后面的修改sp的mov指令會緊跟着一起執行,其原因我覺得可能是為了保護棧,控制棧段大小。
(3)mov命令用於寄存器之間傳送數據時是占2個字節,用在寄存器和數據之間時占3個字節。