1. 程式人生 > >實驗 4 [bx]和 loop 的使用

實驗 4 [bx]和 loop 的使用

一、實驗目的

1. 理解和掌握暫存器間接定址方式[bx]

2.  通過彙編指令 loop 的使用理解程式語言中迴圈的本質

3.  熟練掌握使用 debug 按需除錯完整彙編源程式的方法

 

二、實驗準備

1. 學習/複習第 5 章使用[bx] loop 實現迴圈的程式設計應用示例(教材 5.5 節,5.8 節)

2.  複習第 3 章「棧」的知識

3.  結合第章課件,複習完整彙編源程式編寫→彙編→連線→執行→除錯的方法

 

三、實驗內容

1.  綜合使用

loop,[bx],編寫完整彙編程式,實現向記憶體 b800:07b8 開始的連續 16 個

字單元重複填充字資料 0403H

必做:綜合使用 loop, [bx], mov 實現

實現程式碼如下:

assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax
    mov cx,16
    mov bx,07b8H
    mov ax,0403h

s:  mov [bx],al
    inc bx
    mov [bx],ah
    inc bx
    loop s
mov ax,4c00h int 21h code ends end 

首先當然是設定bx和ds的值,將b800通過ax傳給ds(由於b800是以字母開頭的,所以應當在前面加上一個0),bx的值設為07b8h.

最後將ax的值設為0403h,用於累加

這裡要加16次,顯然要使用loop迴圈,設定cx的值等於16以控制迴圈次數,用inc bx每次bx地址加1

一個字單元是16位的,採用小端法讀字

 

實驗結果如下:

這裡仍然使用了上一個實驗中所使用的process.bat簡化步驟,可以看出輸出結果是一串紅心

 

2.  綜合使用 loop,[bx],編寫完整彙編源程式,實現向記憶體 0:200~0:23F 依次傳送資料

0~63(3FH)。

程式碼如下:

assume cs:code
code segment
        mov ax,20h
        mov ds,ax
        mov bx,0
        mov cx,64

	s:mov [bx],bx
        inc bx
        loop s

        mov ax,4c00h
        int 21h
code ends
end 

首先邏輯地址0:200可以寫成20:0,這樣改寫是為了便於後面bx遞增,通過ax將20h傳入到ds中。

bx初值賦為0,一共需要執行64次,將cx的值賦為64以控制迴圈次數

剛好這裡需要傳送的資料0~63(3FH)與[bx]是一致的,資料0-63是64個連續的數字,0-3fH也是連續的64個編號。

我們可以使用一個bx變數就把偏移地址和數字的遞增都搞定。

所以迴圈段內容就寫成了如上的樣子

實驗結果如下:

似乎沒有什麼變化和輸出,仿照前面實驗的經驗,我們將螢幕清空後再次執行

依然沒有發現有任何的輸出結果,當然這個程式是執行了的,猜測可能改程式沒有輸出,只是在內部記憶體中發生了一些變化。

  

3.  教材實驗 4(3)(P121)

分析過程:

cs段暫存器中儲存的是指向程式程式碼段的段地址。此實驗是將程式的程式碼(按位元組)複製,故將cs暫存器中的指向程式碼的段地址賦值給ax,再通過ax暫存器賦值給ds段暫存器。

所以顯然第一個空應當填寫CS

對於第二個空,我們需要填寫CX的值,即需要知道迴圈的次數,這是重點,此試驗是將"mov ax,4c00h"之前的指令複製到記憶體0:200處

所以沒有執行前我們不知道次數,索性先隨便輸入一個CX值,反彙編看出"mov ax,4c00h"之前的機器碼長度

這裡我們隨機輸了個10,程式碼如下

assume cs:code
code segment
    mov ax,cs       
    mov ds,ax       
    mov ax,0020h
    mov es,ax 
    mov bx,0   
    mov cx,10    

    s:mov al,[bx]     
    mov es:[bx],al  
    inc bx
    loop s

    mov ax,4c00H
    int 21H
code ends
end

  

 

Debug後檢視和反彙編的內容如上

CX的值為1C,即整個程式碼長度

我們發現mov ax,4cooh/int 21h它們共佔用了5個位元組。所以在本實驗中我們需要複製的程式碼位元組數是001CH-0005H=0017H==23個位元組,故cx計數暫存器賦值為23或17H。

故正確的程式碼如下

assume cs:code
code segment
    mov ax,cs       
    mov ds,ax       
    mov ax,0020h
    mov es,ax 
    mov bx,0   
    mov cx,17h    

    s:mov al,[bx]     
    mov es:[bx],al  
    inc bx
    loop s

    mov ax,4c00H
    int 21H
code ends
end

 成功編譯連線後,我們進入Debug,對0020:0(即0:200)處,長度為17h的記憶體進行反彙編,檢視其中的內容

 

經檢視發現確實是mov ax,4c00h"之前的指令複製到記憶體0:200處,實驗成功!!!

 

五、總結與體會

(1)不僅可以向記憶體中寫入資料,還可以複製程式碼

(2)在必須執行過一次才能知道結果的情況下,我們可以先假設再得出準確的數值

(3)loop的作用很大,極大的減少不必要的重複操作