彙編課程實驗 8086指令編碼和除錯
實驗目的
- 掌握8086CPU、暫存器、記憶體(包括棧空間)的基礎知識
- 掌握彙編源程式組成與結構
- 理解和掌握暫存器間接定址方式[bx]
- 掌握彙編指令mov, add, sub, jmp, push, pop,loop的用法,理解高階語言的表達和抽象機制
- 熟練掌握使用debug工具編寫和除錯x86彙編命令的方法
- 掌握組合語言源程式編寫→彙編→連結→除錯的工具和方法
實驗內容
實驗任務1
略
實驗任務2
PC機主機板上的ROM中有一個生產時期,在記憶體FFF00H ~ FFFFFH的某幾個單元中,請找到這個生產時期,並試圖修改它。
- 在debug中,使用d命令檢視生產日期
- 使用e命令修改生產時期所在的記憶體單元,修改後,再次使用d命令檢視
解答
出廠時間儲存在記憶體單元fff0:f5至fff0:fc欄位共8個位元組
使用e命令對從fff0:f5開始的連續8個位元組進行修改 修改完成後使用d命令進行檢視
儲存的值未發生變化,因為只讀儲存器中儲存的值只能被檢視無法被修改
實驗任務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:0f00 0f9f區間批量寫入資料 03 04後 螢幕中打印出如下情形
嘗試修改批量匯入的資料後 螢幕列印的形狀及顏色發生了變化
實驗任務4
在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:棧頂邏輯地址 0023:0 實體地址 00230H
- 問題2:
- 問題3:
與之前相比發生了變化
- 問題4:
與之前相比未發生變化
實驗任務5
在debug環境中,實踐以下內容。
先使用f命令,把00220H ~ 0022fH區間的16個位元組記憶體單元值全部修改為0。並使用d命令檢視確認。
然後,使用a命令、r命令、t命令寫入彙編指令並單步除錯。
觀察並思考:
問題1:使用t命令單步執行 mov ss, ax 時,是單步執行完這一條指令就暫停了嗎?後面的指令 mov sp, 30 是什麼時候執行的?
問題2:根據彙編指令,前三條指令執行後,00220H ~ 0022fH被設定為棧空間。並且,初始時,已通過f命令將初始棧空間全部填充為0。觀察單步除錯時,棧空間00220H ~ 0022fH記憶體單元值的變化,特別是圖示中黃色下劃線表示出的資料值。根據實驗觀察,嘗試思考和分析原因
解答
- 問題1:不是,mov sp:30緊接在mov ss,ax後進行
- 問題2:畫黃線的資料是cs:sp的數值,是由於t單步除錯執行中斷指令將cs和sp暫存器壓棧的操作而導致的結果。
實驗任務6
使用任何一款文字編輯器,編寫8086彙編程式原始碼。
task6.asm
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。執行程式。結合程式執行結果,理解程式功能。
使用debug工具,除錯task5.exe。根據第4章所學知識,任何可執行程式在執行時,都有一個載入程式負責將其載入到記憶體,並將CPU控制權移交給它,也即將CS:IP指向可執行程式中第一條機器指令。在載入可執行程式時,可執行前面512位元組是程式段字首PSP(Program Segment Prefix),用於記錄程式一些相關資訊。
在debug中,使用d命令,檢視task5.exe的程式段字首,觀察這256個位元組的內容,驗證前兩個位元組是否是CD 20
實驗結果:
終端打印出0123456789
實驗任務7
下面程式的功能是,完成自身程式碼的自我複製:把 mov ax, 4c00h 之前的指令複製到記憶體0:200開始的連續的記憶體單元。
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
補全程式,並在debug中除錯驗證,確認是否正確實現了複製要求。
補全後的程式:
assume cs:code
code segment
mov ax, cs
mov ds, ax
mov ax, 0020h
mov es, ax
mov bx, 0
sub cx,5
s: mov al, [bx]
mov es:[bx], al
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end
程式起始指令的地址由CS:IP指定,所以將基址CS的值存入AX中。
迴圈的次數是需要複製的內容的位元組長度,注意到mov ax,4c00h 指令佔用3個位元組,int 21h指令佔用2個位元組,共5個位元組,所以迴圈的長度即CX的值減去5位元組。
檢驗結果: