實驗1 8086匯編指令編碼和調試


實驗結論

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個字節。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM