1. 程式人生 > 實用技巧 >洛谷 P1069 細胞分裂

洛谷 P1069 細胞分裂

1. 實驗任務1

使用任意一款文字編輯器,編寫8086彙編源程式ex1.asm。原始碼如下:

 1 ;ex1.asm
 2 assume cs:code
 3 code segment
 4     mov ax, 0b810h
 5     mov ds, ax
 6     
 7     mov byte ptr ds:[0], 1
 8     mov byte ptr ds:[1], 1
 9     mov byte ptr ds:[2], 2
10     mov byte ptr ds:[3], 2
11     mov byte ptr ds:[4], 3
12     mov byte ptr ds:
[5], 3 13 mov byte ptr ds:[6], 4 14 mov byte ptr ds:[7], 4 15 16 mov ah, 4ch 17 int 21h 18 code ends 19 end

使用masm、link對ex1.asm進行彙編、連結,得到可執行檔案ex1.exe,然後執行該檔案。

使用debug載入可執行檔案ex1.exe後,使用d命令檢視程式段字首PSP所佔的256個位元組。

結合可執行檔案中暫存器CX的值,使用u命令對ex1.exe進行精確反彙編。

使用g命令執行到程式退出執行之前(即原始碼檔案中line16之前),觀察結果。

2. 實驗任務2

使用任意一款文字編輯器,編寫8086彙編源程式ex2.asm。原始碼如下:

 1 ; ex2.asm 
 2 assume cs:code 
 3 code segment 
 4     mov ax, 0b810h 
 5     mov ds, ax 
 6 
 7     mov bx, 0 
 8     mov ax, 101H 
 9     mov cx, 4
10 s:     mov [bx], ax 
11     add bx, 2 
12     add ax, 101H
13     loop s
14 
15     mov ah, 4ch
16     int
21h 17 code ends 18 end

使用masm、link對ex1.asm進行彙編、連結,得到可執行檔案ex2.exe,然後執行該檔案。

結合可執行檔案中暫存器CX的值,使用u命令對ex2.exe進行精確反彙編。

靈活使用t命令、p命令、g命令,對ex2.exe進行除錯。

  首先用g命令執行到loop指令,而後再使用t命令進行單步除錯,發現下一條是int指令時使用p命令,即步過中斷指令。

  第二次嘗試使用t命令進入loop迴圈,一次迴圈結束之後用p命令直接執行完loop,並嘗試用t命令跟蹤INT 21h命令,發現下一指令為STI。通過查閱資料瞭解到該指令全稱為Set Interupt,作用是允許中斷髮生。在STI起效之後,所有外部中斷都被恢復,這樣可以打破被保護程式碼的執行,允許硬體中斷轉而處理中斷的作用。

把ex2.asm中line9 mov cx, 4 改成 mov cx, 8 ,儲存後重新彙編、連結、執行並觀察結果。

結合上述實驗和觀察,分析、對比ex2.asm和ex1.asm,它們實現的是否是相同的功能和效果?在具體實現上有什麼不同?

  二者實現了相同的功能,都是向b810:0000開始的連續8個位元組依次填充1 1 2 2 3 3 4 4,在具體實現上ex1.asm是一條一條指令將資料送入,而ex2.asm是採取迴圈的方式。

3. 實驗任務3

綜合使用loop,[bx],編寫完整彙編程式,實現向記憶體b800:07b8開始的連續16個字單元重複填充字資料0237H。

 1 assume cs:code
 2 code segment
 3     mov ax,0b800h
 4     mov ds,ax
 5     mov bx,07b8h
 6     mov cx,16
 7 s:    mov [bx],0437h
 8     add bx,2
 9     loop s
10     mov ah,4ch
11     int 21h
12 code ends
13 end

執行結果如下,和預期一致。

把填充的字資料,從0237H 改成0239H,再次儲存後,彙編、連結、執行,觀察結果。

把填充的字資料,從0237H 改成0437H,再次儲存後,彙編、連結、執行,觀察結果。

猜測並分析,這個字資料中高位位元組裡存放的是什麼資訊,低位位元組裡存放的是什麼資訊。

  通過對比以上的三張圖片,不難發現第一張與第二張顯示的數字不同,第一張與第三張顯示的顏色不同,故此猜想高位位元組存放的是顏色資訊,低位存放的是字元資訊。

4. 實驗任務4

綜合使用[bx]和loop,編寫彙編源程式,實現向記憶體0:200~0:23F依次傳送資料0~63(3FH)。

 1 assume cs:code
 2 code segment
 3     mov ax,0020h
 4     mov ds,ax
 5     mov cx,64
 6     mov bx,0
 7 s:    mov [bx],bl
 8     add bx,1
 9     add al,1
10     loop s
11     mov ah,4ch
12     int 21h
13 code ends
14 end

彙編、連結無誤後,靈活使用debug的t命令、g命令、p命令除錯。

  結合實驗任務2中所得結論,採用下圖的除錯方式。

在程式退出前,用d命令檢視0:200~0:23F,確認是否將0~3F傳送至此段記憶體區域。

  根據下圖的結果,可以確定已經成功將0~3F傳送至0:200~0:23F。

5. 實驗任務5

詳見教材實驗4(3),完成彙編源程式,實現將“mov ax,4c00h"之前的指令複製到記憶體0:200處。

 1 assume cs:code
 2 code segment
 3     mov ax,cs
 4     mov ds,ax
 5     mov ax,0020h
 6     mov es,ax
 7     mov bx,0
 8     mov cx,17h
 9 s:    mov al,[bx]
10     mov es:[bx],al
11     inc bx
12     loop s
13     mov ax,4c00h
14     int 21h
15 code ends
16 end

  line3和line4的功能是給到程式一個源地址,故填入csline8的功能是設定迴圈次數,可以先隨便填入一個數字,我試驗時填入了7,然後用u命令檢視得到mov ax,4c00h之前的指令一共需要多少位元組。通過下圖可知,一共需要從0到16h的17個位元組,故填入17。

彙編連線後,靈活使用debug的t命令、g命令、p命令除錯。

  本次直接使用g命令除錯整段程式。


用d命令檢視0:200之後的若干位元組,觀察是否將mov ax, 4c00h之前的指令複製到指定記憶體。

  使用d命令可以得到如下的結果。

  使用u命令進行反彙編,確定此時mov ax, 4c00h之前的指令已經複製到指定位置。