1. 程式人生 > 實用技巧 >優雅的提交你的Commit

優雅的提交你的Commit

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之前),觀察結果。

1、對ex1.asm進行編譯,連線,執行:

(1、使用masm進行編譯,執行結果如圖:

(2、使用link進行連線,執行結果如圖:

(3、檢視當前目錄,可發現編譯和連線生成的.obj檔案和.exe檔案,如圖:(編譯和連線過程中使用預設檔名)

(4、執行ex1.exe檔案(執行在docbox中進行),執行結果如圖::

2、使用debug工具對可執行檔案進行除錯:

(1、使用debug指令除錯ex1.exe檔案:

(2、使用d命令檢視檢視程式段字首PSP所佔的256個位元組

(3、使用u命令進行反彙編:

(4、使用g命令執行程式:

(5、使用d命令檢視程式修改的地址段的內容,如圖

使用g指令實行程式前:

使用g指令實行程式後:

發現該段記憶體單元的值不是理論值,執行完成程式之後該段地址中前八個位元組的資料應為:01 01 02 02 03 03 04 04,但查詢結果與之不符。

(6、退出debug工具,使用cls命令清屏之後,再次執行程式,可看到在當前頁面上出現特殊字元,再次檢視該段地址的資料,發現數據與理論值相同

(7、再次執行,下圖為頁面內容滾動前和滾動後d指令查詢結果,發現頁面滾動後,查詢結果就立刻發生變化

結論:地址段A0000~BFFFF為視訊記憶體地址空間,該段地址中資料發生變化在顯示頁面會做出響應(如本實驗中出翔特殊字元),隨著頁面內容的增多,

當頁面內容滾動造成的當親啊顯示頁面內容的變化,對應的地址空間中的資料也會發生改變,也就是為什麼在使用debug工具除錯步驟中使用d指令檢視

的資料資料不是理論值的原因。

二. 實驗任務2
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

要求:

  使用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,它們實現的是否是相同的功能和效果?在具體實現上有什麼不同?

1、對ex2.asm進行編譯,連線,執行:

  (1、編譯

  (2、連線

(3、執行:(在docbox中執行)

(4、修改:將ex2.asm中line9 mov cx, 4 改成mov cx, 8,執行結果如圖:(在docbox中執行)

可發現圖示發現變化。

2、使用debug工具對可執行檔案進行除錯:

(1、使用debug指令除錯ex2.exe檔案:

(2、使用u指令進行反編譯:

(3、使用g指令執行程式,並檢視執行前後段地址B810中偏移地址0~F內容的變化:

發現結果不是理論值。

(4、再次使用debug工具進行除錯:

執行一次迴圈,過程中頁面內容未滾動,檢視該段地址中的資料,發現數據被寫入到該段記憶體地址中與理論值相同

繼續除錯,隨著內容的增多,頁面滾動,視訊記憶體地址b810:0~f 所對應的顯示頁面上內容的變化,該段地址中儲存的資料也發生變化

繼續除錯,迴圈執行完四次之後跳出迴圈,程式執行結束如圖:

回答問題:

結合上述實驗和觀察,分析、對比ex2.asm和ex1.asm,它們實現的是否是相同的功能和效?

  通過可執行檔案ex1.exe和ex2.exe的執行結果來看,ex2.asm和ex1.asm執行的是相同的功能。ex1.asm是單獨通過mov指令改

  寫地址b810:0~f 中的內容,ex2.asm通過迴圈

三. 實驗任務3
原始碼

; ex3.asm
assume cs:code
    code segment
        mov ax, 0b800h
        mov ds, ax
        mov bx, 07b8h
        mov ax, 0237h
        mov cx, 8h
        s: mov [bx], ax
        add bx, 2h
        loop s
        mov ah, 4ch
        int 21h
    code ends
end

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

要求:把填充的字資料,從0237H 改成0239H,再次儲存後,彙編、連結、執行,觀察結果。
   把填充的字資料,從0237H 改成0437H,再次儲存後,彙編、連結、執行,觀察結果。
   猜測並分析,這個字資料中高位位元組裡存放的是什麼資訊,低位位元組裡存放的是什麼資訊。

(1、執行惡行.exe檔案,執行結果如圖:

2、修改程式中的資料:0237H 改成0239H,再次儲存後,彙編、連結、執行,執行結果如圖:

(3、修改程式中的資料:0237H 改成0437H,再次儲存後,彙編、連結、執行,執行結果如圖:

  使用debug除錯產看寫入的資料,如圖:

資料寫入正確。

結論:三次測試,第一次填入的資訊是:0237H;執行結果:7777777777777777(綠色)

        第二次填入的資訊是:0239H;執行結果:9999999999999999(綠色)

        第三次填入的資訊是:0437H;執行結果:7777777777777777(紅色)

   通過對比:一、三低地址中內容相同,高地址不同,結果都為串7,顏色不同

   通過對比:一、二低地址中內容不同,高地址相同,結果顏色相同,顯示的字串不同

   可以猜測高地址存放的資料是顯示字元的顏色對應的十六進位制數,低地址存放的資料與是顯示的字元對應的十六進位制數(30~39對應0~9)

四. 實驗任務4
程式原始碼

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

要求:彙編、連線接無誤後,靈活使用debug的t命令、g命令、p命令除錯,用d命令檢視0:200~0:23F,確認是否將0~63傳送至此段記憶體區域。

1、對ex1.asm進行編譯,連線,執行:(在docbox中進行)

(1、使用masm進行編譯,執行結果如圖:

(2、使用link進行連線,執行結果如圖:

2、使用debug工具對可執行檔案進行除錯:(除錯在docbox中進行)

(1、使用debug指令除錯ex4.exe檔案

(2、執行程式,在執行前後檢視地址200~23f 中的的資料,執行結果如圖:

執行結果顯示,地址200~23f 中的的資料資料發生改變,而且與理論值相同。

3、使用棧(編譯連線過程跳過)

; ex4_1.asm
assume cs:code
    code segment
        mov ax, 1000h
        mov ss, ax
        mov sp, 0240h
        mov al, 00h
        mov ah, 01h
        mov cx, 64
        s0:push ax
        add ah, 2h
        add al, 2h
        loop s0    
        
        mov ax, 1020h
        mov ds, ax
        mov ax, 0h
        mov ss, ax
        mov sp, 0240h
        mov bx, 0h
        mov cx, 32
        s:push [bx]
        add bx, 2
        loop s

        mov ah, 4ch
        int 21h
    code ends
end

(1、除錯ex4_1.exe程式,使用d指令檢視程式執行前的地址段資料

(2、執行程式

(3、執行後查詢地址段資料,資料被寫入。

五. 實驗任務5
原始碼

; ex5.asm
assume cs:code      ;
    code segment
        mov ax,cs    ;cs指向程式儲存的地址
        mov ax,0020H
        mov es,ax    ;es賦值資料儲存的目標地址
        mov bx,0
        mov cx,20      ;一次只複製一個位元組,需要迴圈20次
        S:mov al,[bx]  ;將資料取出傳遞到暫存器al中
        mov es:[bx],al  ;通過暫存器al將資料傳遞到目標地址中
        inc bx
        loop s
        mov ax,4c00H
        int 21h
    code ends
end

1、對ex5.asm進行編譯,連線,執行:(在docbox中進行)

(1、使用masm和link對程式進行編譯,連線,執行結果如圖:

2、使用debug工具對可執行檔案進行除錯:(在docbox中進行)

(1、使用debug指令除錯ex1.exe檔案:

(2、除錯前檢視原地址的資料和目標地址段的資料,如圖:

(3、除錯,給出一個迴圈的除錯步驟,如圖:

(4、一個迴圈結束後再次檢視目標地址的資料,如圖:

可以看到一個迴圈結束之後已經將一個數據存入到目標地址中。

(5、使用g指令執行程式,並在執行後檢視原地址的資料和目標地址段的資料,如圖:

執行結果顯示,資料被正確的複製到目的地址段(前二十個位元組)。

複製的是指令在記憶體中對應的編碼。

起始位置的確定:CS暫存器是程式碼段暫存器,對應於記憶體中的存放程式碼的記憶體區域,用來存放記憶體程式碼段區域的入口地址(段基址)

第一個空:mov ax,____ 填入cs。

賦值的位元組數量:機器指令在記憶體中以資料的形式儲存,以位元組為單位,首先隨機填一個值通過mov指令傳遞給cx暫存器,是程式能夠通過

編譯和連線,在使用debug工具除錯,使用u指令反編譯檢視車程式儲存的地址單元,以此通過位元組數來確定迴圈次數。在回頭去更改程式。

2、實驗總結

  (1)、注意事項:

      通過文字編輯器編寫程式,程式中的十六進位制數需要帶上h,否則再執行過程中會被當成十進位制數。

      通過文字編輯器編寫程式,需要使用記憶體單元時不能直接使用“[偏移量]“的形式,需要通過暫存器來傳遞偏移量:[暫存器]

      編譯、連線、除錯檔案字尾名問題:編譯和連線時可以不帶檔案的字尾名,但是在使用debug命令除錯時需要帶上檔案字尾名,否則執行報錯

(2)、可將程式分為兩部分:偽指令和可執行程式碼段

    assume cs : 段名        (偽指令:將作用程式碼段和CUP中的段地址暫存器cs聯絡起來【如實驗中使用的code只是一個標號】)

      段名 segment        (偽指令:段開始【和code ends 成對使用】)

        可執行程式碼段......

      段名 ends         (偽指令:段結束)

    end              (偽指令:彙編程式結束的標記)

    可執行程式碼段中包括程式的返回:mov ax, 4c00H int 21H (由這兩條指令實現程式的返回功能)