1. 程式人生 > 實用技巧 >實驗2 彙編源程式編寫與彙編除錯

實驗2 彙編源程式編寫與彙編除錯

實驗結論

實驗任務1


;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
  • 對ex1.asm進行彙編、連結、執行

分析ex1.asm可知,程式碼將1、1、2、2、3、3、4、4賦值給了0b810:0開始的8個連續記憶體單元,將在螢幕上輸出影象,與執行結果一致


  • 使用r命令,得到CX=0031;因此使用u ds:0 30進行反彙編得到如下結果

  • 使用d ds:0 L100即可檢視段字首PSP所佔的256個位元組

由執行結果可知,段字首PSP的內容大部分為無法顯示的字元,在少數可顯示字元中明顯有著ex1.exe即該可執行程式的檔名字樣

  • 根據反彙編結果,使用g命令執行到程式退出之前,即AH,4C之前

  • 使用命令g cs:2D

使用g命令後,螢幕右上角出現了和直接執行檔案時相同的影象


實驗任務2

;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
  • 直接執行:

與實驗一併無差別

  • 反彙編:

  • 除錯:

    • 先使用g cs:e

      執行到進入迴圈之前

    • 使用t命令單步執行

    • 在執行LOOP 000E分別使用tp指令作對比


      LOOP 000E處:使用t指令時,下一步指令會跳轉至000E處,迴圈執行
      p指令會執行至下一條指令
      t指令:逐語句除錯p指令:逐過程除錯

  • 將程式碼第九行mov cx,4改為mov cx,8

    • 重新彙編連結
    • 使用debug,使用g命令執行到退出程式之前
      • 對比修改前後ax,bx變化可知,迴圈次數從4次變成了8次
        修改前 修改後
        ax 0505H 0909H
        bx 0008H 0010H
  • 同樣是對連續的記憶體單元賦值,ex1.asm是人工重複賦值,而ex2.asm是使用迴圈結構使程式自動賦值,

  • 兩者雖然執行結果和功能是一樣的,但當需要改變的記憶體單元個數較多時,顯然前者是不合適的


實驗任務3

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

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

  • 把填充的字資料從0237H改為0239H

顯示結果顏色不變,字元從7變成了9


  • 把填充的字資料從0237H改為0437H

顯示結果顏色變為了紅色,字元不變

  • 據此分析,這個字資料中高位位元組存放的顏色資訊,低位位元組存放的字元的ASCII碼資訊

實驗任務4

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

        mov bx,200H
        mov dx,0H;
        mov cx,40H
s:      mov [bx],dx
        inc bx,1
        inc dx;
        loop s
        mov ah,4ch
        int 21h
code ends
end

使用d命令檢視0:200~0:23F可得成功修改相應記憶體空間的值


實驗任務5

;ex3.asm
assume cs:code
code segment
        mov ax,cs
        mov ds,ax
        mov ax,0020h
        mov es,ax
        mov bx,0
        mov cx,18h
s:      mov al,[bx]
        mov es:[bx],al
        inc bx
        loop s
        mov ax,4c00h
        int 21h
code ends 0
end
  1. 題目要求將本程式複製到指定位置,那麼就需要記錄本程式的起始地址和程式長度
  2. 顯然mov al,[bx];mov es:[bx],al即為複製語句,將 [bx]複製到es:[bx],因此ds對應的即為本程式的起始地址,es為目標地址,所以第一空填cs
  3. 第二空18h通過重複試驗得到、
  • 使用debug的u指令進行反彙編

觀察反彙編結果各語句的ip得:18即為語句mov ax,4c00hmov ax,cs的長度

  • 使用d 命令檢視0:200開始的長度為1D的連續記憶體單元

發現程式以及成功複製到了0:200開始的記憶體單元,且LOOP語句處的跳轉地址也成功自動改為了0210


實驗總結

  1. 彙編程式的執行步驟:
    1. masm ex1.asm; 彙編
    2. link ex1.obj; 連結
    3. ex1 或 debug ex1.exe 執行/debug除錯
  2. t命令:逐語句

    p命令:逐過程
  3. LOOP指令:標記位置s,cx為迴圈次數