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


四、實驗結論


2. 實驗任務2
  • PC機主板上的ROM中有一個生產時期,在內存FFF00H ~ FFFFFH的某幾個單元中,請找到這個生產時期,並試圖修改它。
  • 在debug中,使用d命令查看生產日期。
  • 使用e命令修改生產時期所在的內存單元,修改后,再次使用d命令查看。
 
查看命令及結果如下:
修改命令及查看結果如下:

結論:不可修改,因為該段內存是ROM的內存單元,只能讀,不能修改


3. 實驗任務3
  • 在debug中,使用e命令,向內存單元填寫數據。
  -e b800:0 03 04 03 04 03 04 03 04 03 04

  b800:0開始的內存單元開始,依次寫入十六進制數據04 03,重復寫5次。

  • 在debug中,使用f命令,向內存單元批量填寫數據。
  -f b800:0f00 0f9f 03 04
  把內存單元區間b800:0f00 ~ b800:0f9f連續160個字節,依次重復填充十六進制數據03 04。
  
  注*:
  1. 為了方便觀察實驗效果,在dosbox環境輸入 debug 進入debug調試環境前,先輸入DOS命令 cls 清 除一下屏幕。
  2. 嘗試修改內存地址,或,嘗試修改內存的數據,再次觀察結果。 
 
命令及效果截圖如下:

修改內存數據后效果截圖:

 


4. 實驗任務4
  已知內存單元00201H ~ 00207H分別存放數據(如下圖所示),00220H ~ 0022fH用作棧空間。
       
  在debug環境中,按順序錄入以下內容,單步跟蹤調試,觀察寄存器和內存空間00200H~00207H,以及,棧空間00220 ~ 0022fH內容變化情況。記錄實驗結果。回答問題,驗證和你的理論分析結果是否一致。
       

  (1) 單步執行,在執行push指令和pop指令時,觀察並記錄棧頂偏移地址的寄存器sp值的變化情況。

  (2) push [6] 指令執行結束后, pop [6] 指令執行結束前,使用d命令 d 20:20 2f 查看此時棧空間的數據。
  (3) pop [0] 指令執行結束后,使用d命令 d 20:0 7 查看此時數據空間內的數據是否有變化。
  (4) 如果把最后四條指令改成截圖中的順序, pop [6] 指令執行結束后,使用d命令 d 20:0 7 查看此時數據空間內的數據是否有變化。  

       

  •  填空
 1 -a
 2 mov ax, 20
 3 mov ds, ax
 4 mov ss, ax
 5 mov sp, 30
 6 push [0] ; 執行后,寄存器(sp) = 002E
 7 push [2] ; 執行后,寄存器(sp) = 002C
 8 push [4] ; 執行后,寄存器(sp) = 002A
 9 push [6] ; 執行后,寄存器(sp) = 0028
10 pop [6] ; 執行后,寄存器(sp) = 002A
11 pop [4] ; 執行后,寄存器(sp) = 002C
12 pop [2] ; 執行后,寄存器(sp) = 002E
13 pop [0] ; 執行后,寄存器(sp) = 0030
  • 回答問題

  問題1:題目要求是把00220H ~ 0022fH用作棧空間。指令 mov ss, ax 和 mov sp, 30 執行后,棧頂的邏輯地址和物理地址分別是?

  棧頂邏輯地址:0020:0030

  物理地址:00230H

 

  問題2:單步調試到匯編指令 push [6] 執行結束, pop [6] 執行之前,使用 d 20:20 2f 查看此時棧空間數據,給出實驗截圖。

     
 

   問題3 :匯編指令 pop [0] 執行結束后,使用d命令 d 20:0 7 查看此時數據空間內的數據是否有變化。給出實驗截圖。

   數據空間內數據有變化。
  
 

  問題4:如果把最后四條指令改成截圖中的順序, pop [6] 指令執行結束后,使用d命令 d 20:0 7查看此時數據空間內的數據是否有變化。給出實驗截圖。

   數據有變化。
       

5. 實驗任務5 

  在debug環境中,實踐以下內容。 
       
  • 回答問題1和問題2。

  問題1:使用t命令單步執行 mov ss, ax 時,是單步執行完這一條指令就暫停了嗎?后面的指令 movsp, 30 是什么時候執行的?

  使用t命令單步執行 mov ss, ax 時,不是單步執行完這一步就暫停。Debug的T命令在執行修改寄存器SS的指令時,下一條指令也緊接着被執行。

 

  問題2:根據匯編指令,前三條指令執行后,00220H ~ 0022fH被設置為棧空間。並且,初始時,已通過f命令將初始棧空間全部填充為0。觀察單步調試時,棧空間00220H ~ 0022fH內存單元值的變化,特別是圖示中黃色下划線表示出的數據值。根據實驗觀察,嘗試思考和分析原因。 

   原因:通過查閱資料,在一篇博客中提到棧的分配會多分配5個字的單元。一般,堆棧中存放的多是各個寄存器的值以保持程序環境。而T命令的具體壓棧流程為PUSHF,PUSH CS,PUSH IP,PUSH BP,PUSH AX。所以在T命令單步執行時,將此時CS IP的值存入了棧中。


6. 實驗任務6

  使用任何一款文本編輯器,編寫8086匯編程序源碼。
  task6.asm
 1 assume cs:code
 2 
 3 code segment
 4     start:
 5     mov cx, 10
 6     mov dl, '0'
 7      s: mov ah, 2
 8     int 21h
 9     add dl, 1
10     loop s
11     
12     mov ah, 4ch
13     int 21h
14 code ends
15 end start
  • 使用masm、link,匯編、鏈接,得到可執行文件task6.exe。運行程序。結合程序運行結果,理解程序功能。
  • 使用debug工具,調試task6.exe。根據第4章所學知識,任何可執行程序在執行時,都有一個引導程序負責將其加載到內存,並將CPU控制權移交給它,也即將CS:IP指向可執行程序中第一條機器指令。在加載可執行程序時,可執行前面512字節是程序段前綴PSP(Program Segment Prefix),用於記錄程序一些相關信息。
  • 在debug中,使用d命令,查看task6.exe的程序段前綴,觀察這256個字節的內容,驗證前兩個字節是否是CD 20。 
程序源碼如下:
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

對程序匯編、鏈接過程截圖如下:

查看程序段前綴及運行結果截圖如下:

 

驗證得到PSP的首兩個字節是CD 20。


7. 實驗任務

  下面程序的功能是,完成自身代碼的自我復制:把 mov ax, 4c00h 之前的指令復制到內存0:200開始的連續的內存單元。
  補全程序,並在debug中調試驗證,確認是否正確實現了復制要求。
  task7.asm
 1 assume cs:code
 2 code segment
 3     mov ax, ①
 4     mov ds, ax
 5     mov ax, 0020h
 6     mov es, ax    
 7     mov bx, 0
 8     mov cx, ②
 9     s: mov al, [bx]
10     mov es:[bx], al
11     inc bx
12     loop s
13 
14     mov ax, 4c00h
15     int 21h
16 code ends
17 end
  • 給出補全后的完整源碼。說明程序中兩個空填寫的依據。
    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,所以將cs指向地址賦值給寄存器ax,再通過ax存入數據段地址ds。

    ②寄存器cx中存放的是可執行文件長度,因此可以先隨便賦值給cx,進行debug,然后通過r命令得到cx為21h,而要求復制mov ax, 4c00h 之前的指令,因此cx值21h-5h=17h。

 

  • 在debug中調試,使用g命令將程序執行到 loop s 之后、 mov ax, 4c00h 之前,然后,使用u命令對0:200開始的內存單元反匯編,確認是否把task7.asm中line3-line12的代碼復制到了目標內存空間。給出使用g命令運行到指定點和使用u命令反匯編0:200到復制代碼長度這一段內存空間的截圖。 

   驗證代碼截圖如下:

          

 


 

五、實驗總結:

①邏輯地址=段地址:偏移地址  

物理地址=段地址*16+偏移地址

寫匯編源程序時,默認是十進制。對於十六進制,需手動添加H。如: mov ax, 30H。而debug工具中默認是十六進制。

③使用debug調試時,調試的必須是可執行文件,並且要帶擴展名。即: debug ××.exe。

④使用debug ××.exe調試時,首次進入調試界面時,寄存器CX中存放的是可執行文件長度。可以通過u命令,結合CS、IP、CX的值,對  *.exe文件反匯編,得到匯編源程序。

⑤程序加載后,ds中存放着程序所在內存區的段地址,這個內存區的偏移地址為0,所以程序所在內存區的地址為ds:0;而這個內存區的前256個字節存放的PSP,用來和程序通信;這個256字節之后的空間存放程序。

另外CS=DS+10h,這里的10h的內容就是PSP(程序段前綴),也就是說程序中最為核心的指令部分從CS:IP指向的內存單元開始。

⑥將匯編語言源程序經過匯編(編譯)后生成的二進制的機器指令代碼,用U指令變為助記符形式的匯編指令,稱為反匯編。

 

 
 
 
 
 
 
 
 
 
 


免責聲明!

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



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