­

實驗2 彙編源程式編寫與彙編、調試

  • 2020 年 11 月 2 日
  • 筆記
一、實驗目的
  1. 理解並掌握彙編源程式組成與結構
  2. 掌握彙編語言源程式編寫→彙編→鏈接→調試的工具和方法
  3. 理解彙編源程式中地址表示、段暫存器的用法
  4. 理解和掌握暫存器間接定址方式[bx]
  5. 通過彙編指令loop的使用理解程式語言中循環的本質
二、實驗準備
  1. 學習/複習第5章使用[bx]和loop實現循環的編程應用示例(教材5.5節,5.8節)
  2. 複習第3章「棧」的知識
  3. 結合第4章課件,複習完整彙編源程式編寫→彙編→連接→運行→調試的方法
  4. 複習8086彙編中記憶體單元地址的表示,以及段暫存器DS, SS, ES, CS的用途
三、實驗內容
 
1. 實驗任務1
使用任意一款文本編輯器,編寫8086彙編源程式ex1.asm。源碼如下:
;ex1.asm
assume cs:code
code segment
    mov ax,0b810h
    mov ds,ax

    mov byte ptr ds:[0],1
    mov byte ptr ds:[1],1
    mov byte ptr ds:[2],2
    mov byte ptr ds:[3],2
    mov byte ptr ds:[4],3
    mov byte ptr ds:[5],3
    mov byte ptr ds:[6],4
    mov byte ptr ds:[7],4

    mov ah,4ch
    int 21h
code ends
end
要求:使用8086彙編程式編寫、彙編、鏈接、運行、調試方法,對ex1.asm進行彙編、鏈接、運行,使用debug工具調試可執行文件。
  • 使用masm、link對ex1.asm進行彙編、鏈接,得到可執行文件ex1.exe,運行並觀察結果。
  • 使用debug工具對程式進行調試
    • 使用debug載入可執行文件ex1.exe後,使用d命令查看程式段前綴PSP所佔的256個位元組。
    • 結合可執行文件中暫存器CX的值,使用u命令對ex1.exe進行精確反彙編
    • 使用g命令執行到程式退出執行之前(即源碼文件中line16之前),觀察結果。

 debug調試:

 • d命令查看程式段前綴PSP所佔的256個位元組。

  • u命令反彙編

  • g命令執行到程式退出執行之前

 

2. 實驗任務2
使用任意一款文本編輯器,編寫8086彙編源程式ex2.asm。源程式碼如下:
;ex2.asm
assume cs:code
code segment
    mov ax,0b810h
    mov ds,ax

    mov bx,0
    mov ax,101H
    mov cx,4
s:    mov [bx],ax
    add bx,2
    add ax,101H
    loop s
    mov ah,4ch
    int 21h
code ends
end
要求:使用8086彙編程式編寫、彙編、鏈接、運行、調試方法,對ex2.asm進行彙編、鏈接、運行,使用debug工具調試可執行文件。
  • 使用masm、link對ex2.asm進行彙編、鏈接,得到可執行文件ex2.exe,運行並觀察結果。
  • 使用debug工具對程式進行調試。
    • 結合可執行文件中暫存器CX的值,使用u命令對ex2.exe進行精確反彙編
    • 靈活使用t命令、p命令、g命令,對ex2.exe進行調試。(不一定要單步,有些地方可以用g命令,一次執行多行彙編指令)
    • 注意:單步調試時,對於循環指令loop, 中斷指令int,使用t命令和p命令單步調試的區別。
  • 把ex2.asm中line9 mov cx, 4 改成 mov cx, 8 ,保存後重新彙編、鏈接、運行並觀察結果。
  • 結合上述實驗和觀察,分析、對比ex2.asm和ex1.asm,它們實現的是否是相同的功能和效果?在具體實現上有什麼不同

dubug調試:

 單步調試循環指令loop:

 

 

 單步調試中斷指令int:

loopint時直接用P命令:

 經觀察發現,t命令單步執行,每次只執行一條程式碼語句,遇到子程式後進入子程式逐條執行指令。p命令,類似t命令。若有子程式,直接執行完子程式全部指令而不是逐條執行指令,在遇到循環指令loop時,會直接執行志cx遞減至0。

ex2.asm中line9為mov cx, 4時:

改成 mov cx, 8 ,保存後重新彙編、鏈接、運行:

ex2.asm和ex1.asm,它們實現的是否是相同的功能和效果?在具體實現上有什麼不同

通過上述實驗可知,他們實現的功能和效果相同,都完成了圖案的輸出。

具體實現上,ex1.asm使用了byte ptr的形式直接填入了8個數,而ex2.asm使用了loop循環將值存入顯示記憶體。

 

3. 實驗任務3
綜合使用loop,[bx],編寫完整彙編程式,實現向記憶體b800:07b8開始的連續16個字單元重複填充字數據0237H。
要求:
  • 編寫彙編源程式、給出運行結果截圖。
  • 把填充的字數據,從0237H 改成0239H,再次保存後,彙編、鏈接、運行,觀察結果。
  • 把填充的字數據,從0237H 改成0437H,再次保存後,彙編、鏈接、運行,觀察結果。
猜測並分析,這個字數據中高位位元組里存放的是什麼資訊,低位位元組里存放的是什麼資訊。

 (1)填充數據0237H

;ex2.asm
assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax

    mov bx,07b8h
    mov ax,0237H
    mov cx,10h
s:    mov [bx],ax
    add bx,2
    loop s
    mov ah,4ch
    int 21h
code ends
end

(2)填充數據0239H

 

 (3)填充數據0437H

 

 觀察後猜想:高位位元組存放的是顏色資訊,低位位元組是內容資訊。

 

4. 實驗任務4
編寫完整彙編源程式,實現向記憶體0:200~0:23F依次傳送數據0~63(3FH)。
♦ 必做
  • 綜合使用[bx]和loop,編寫彙編源程式
  • 靈活使用debug的t命令、g命令、p命令調試。在程式退出前,用d命令查看0:200~0:23F,確認是否將0~3F傳送至此段記憶體區域。
♦ 選做*
  • 利用棧的特性,綜合使用loop,push實現(限定僅使用8086中已學過指令實現),編寫源程式
  • 靈活使用debug的t命令、g命令、p命令調試。在程式退出前,用d命令查看0:200~0:23F,確認是否將0~3F傳送至此段記憶體區域。
♦ Tips:
這道練習,本質上就是把一組連續的位元組數據(常數),送到指定的連續的位元組單元。
如果利用棧實現,藉助push和loop實現連續入棧操作。需要注意:
① 初始時ss和sp的設置
② 8086的入棧操作,是從高地址單元→低地址單元方向的;
③ 8086的入棧操作,只能以字為單元。但這裡是位元組數據,如何靈活處理?

必做:

; ex4.asm
assume cs:code
code segment
    mov ax, 0h
    mov ds, ax
    mov bx, 200h
    mov al, 0h
    mov cx, 40H
    s: mov [bx], ax
    add bx, 1
    add ax, 1
    loop s
    mov ah, 4ch
    int 21h
code ends
end

調試並用d命令查看數據是否存入此段記憶體區域:

 

 選做:

8086的入棧操作是從高地址向低地址,所以設置棧的段地址ss為0h,設置sp為0240h。又因8086入棧操作只能以字為單元。所以ax初始為3F3Eh,小端法棧里添加。

;ex44.asm
assume cs:code
code segment
    mov ax,0h
    mov ss,ax
    mov ax,0240h
    mov sp,ax
    mov ax,3F3Eh
    mov cx,20h
s:    push ax
    add ax,-0202h
    loop s
    mov ah,4ch
    int 21h
code ends
end
    
    
    

調試並用d命令查看數據是否存入此段記憶體區域:

 

5. 實驗任務5
教材實驗4(3)(P121)
♦ Tips:
這道練習,本質仍然是複製,只不過複製的是自身程式碼。填空的關鍵是,如何確定複製多少位元組

 在確定複製多少位元組時,可以先隨意補全,用u命令精準反彙編,找到mov  ax, 4c00h。來確定要複製的位元組數。

 

 反彙編後可知 mov ax,4c00 命令位於0018h。所以要複製0-0017h所有位元組,因此將0017複製給cx。由暫存器cs知要複製的程式碼位於076A段,所以將076A賦值給AX。

assume cs:code
code segment
    mov ax,076Ah
    mov ds,ax
    mov ax,0020h
    mov es,ax
    mov bx,0
    mov cx,0017h
s:    mov al,[bx]
    mov es:[bx],al
    inc bx
    loop s
    mov ax,4c00h
    int 21h
code ends
end

運行結果:

 

 彙編語言調試完畢後,反彙編查看記憶體單元 0:200-0:217處。發現複製成功。