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


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

  可以看到生產日期存儲在內存單元FFF0:00F0到00FF之間,使用-e命令嘗試對其進行修改后發現該內存單元的值並沒有改變。因為該部分內存是受到保護的,為了安全並不支持程序員對其進行修改。

 

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。

  內存區域b800:0~b800:0FFF是顯存區域,修改此處的值可以直接在窗口中看到輸出。

  值得注意的是上述例子中03表示16進制下字符ASCII碼的值,04表示顏色參數。分別對其進行修改可以看到不同的結果輸出。例如:

 

 

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

  

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

 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

 

  (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 查看此時數據空間內的數據是否有變化。 
5. 實驗任務5
  在debug環境中,實踐以下內容。
  先使用f命令,把00220H ~ 0022fH區間的16個字節內存單元值全部修改為0。並使用d命令查看確認。然后,使用a命令、r命令、t命令寫入匯編指令並單步調試。

 

  
  對寄存器ss賦值之后cpu不會相應中斷,會直接跳到下一步執行,故指令 mov ss, ax 單步執行完成后,后一條指令 mov sp, 30 會馬上執行。
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。運行程序。結合程序運行結果,理解程序功能。

   執行結果如下:

  程序功能為依次輸出 0~9 共10個字符。

  使用debug工具,調試task6.exe。根據第4章所學知識,任何可執行程序在執行時,都有一個引導程序負責將其加載到內存,並將CPU控制權移交給它,也即將CS:IP指向可執行程序中第一條機器指令。在加載可執行程序時,可執行前面512字節是程序段前綴PSP(Program Segment Prefix),用於記錄程序一些相關信息。 

  在debug中,使用d命令,查看task6.exe的程序段前綴,觀察這256個字節的內容,驗證前兩個字節是否是CD 20。 

 

7. 實驗任務7
  下面程序的功能是,完成自身代碼的自我復制:把 mov ax, 4c00h 之前的指令復制到內存0:200開始的連續的內存單元。
  補全程序,並在debug中調試驗證,確認是否正確實現了復制要求。
  task7.asm
 1 assume cs:code
 2 
 3 code segment
 4     mov ax, __
 5     mov ds, ax
 6     mov ax, 0020h
 7     mov es, ax
 8     mov bx, 0
 9     mov cx, __
10     s:  mov al, [bx]
11     mov es:[bx], al
12     inc bx
13     loop s
14 
15     mov ax, 4c00h
16     int 21h
17 code ends
18 end

  (1) 補全程序。說明這樣填寫的依據。

  因為要復制程序指令,將程序段初始地址賦值給數據段,故第一個空填cs。

  第二個空隨便填寫一個數據,debug時反匯編程序,如下圖:

  注意到方框中的字節數為23,表示所復制部分指令的字節數。轉換為16進制為0017H,故第二空填0017H。

  補全程序如下:

 1 assume cs:code
 2 
 3 code segment
 4     mov ax, cs
 5     mov ds, ax
 6     mov ax, 0020h
 7     mov es, ax
 8     mov bx, 0
 9     mov cx, 0017h
10     s:  mov al, [bx]
11     mov es:[bx], al
12     inc bx
13     loop s
14 
15     mov ax, 4c00h
16     int 21h
17 code ends
18 end
  重新匯編、鏈接:
  (2) 在debug中調試,使用g命令將程序執行到 loop s 之后、 mov ax, 4c00h 之前,然后,使用u命令對0:200h開始的內存單元反匯編,確認是否把task7.asm中line3-line12的代碼復制到了目標內存空間。
  調試結果如下:

  可以看到代碼已經復制到了目標內存空間。

五、實驗總結

  匯編語言編寫程序是直接對內存進行操作,可以節省很多存儲空間和運行時間。但是程序編寫時的邏輯相對復雜,以及匯編語言默認的16進制數字並不符合我們常用數字的習慣,這使得匯編語言的學習中需要考慮的面更加多了。匯編程序的編寫也需要投入更大量的經歷。


免責聲明!

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



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