實驗目的
- 掌握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字節。
檢驗結果: