1. 程式人生 > >實驗九:根據材料程式設計

實驗九:根據材料程式設計

實驗任務一

 要求:補全程式 t1.asm,完成在螢幕上輸出記憶體單元中的十進位制兩位數。

 1 ;t1.asm
 2 ; 在螢幕上輸出記憶體單元中的十進位制兩位數
 3 assume cs:code, ds:data
 4 data segment
 5      db 12
 6      db ?,?   ; 前一個位元組用於儲存商,後一個位元組用於儲存餘數
 7 data ends
 8 code segment
 9 start:
10       ××××
11       ××××        ; 補全指令,使得ds <-- data段地址
12 13 mov ah,0 14 mov al,ds:[0] ; ax <-- data段位元組單元的被除數12 15 mov bl,10 16 div bl 17 mov ××,al ; 補全程式碼,讓商儲存到data段註釋中指定的單元 18 mov ××,ah ; 補全程式碼,讓餘數儲存到data段註釋中指定的單元 19 20 mov ah,2 21 mov dl,×× ; 補全程式碼,使得dl <-- data段中儲存的商的位元組單元數值
22 ×××× ; 補全程式碼,使得dl中的數值轉換為數字字元 23 int 21h 24 25 mov ah,2 26 mov dl,×× ; 補全程式碼,使得dl <-- data段中儲存餘數的位元組單元數值 27 ×××× ; 補全程式碼,使得dl中的數值轉換為數字字元 28 int 21h 29 30 mov ax,4c00h 31 int 21h 32 code ends 33 end start

補充好的程式碼為:

執行結果:

小結:

此題要求輸出一個十進位制兩位數,以目前所學知識還不能一次性列印2個甚至多個字元,只能一個一個的分別獲取該數字的個位和十位,然後依據ASCLL碼轉換為對應的字元進行輸出。而關鍵就在於如何獲取個位和十位數字,這裡我們採用了除法(div)指令來達到這個目的。

讓10除兩位數,得到的商即是該兩位數的十位數字,得到的餘數即是該兩位數的個位數字。

實驗任務二

要求:補全程式 t2.asm,完成在螢幕上輸出 data 段定義的 5 個十進位制兩位數,資料和資料之間以空格間隔。

 1 ;t2.asm
 2 assume cs:code, ds:data
 3 data segment
 4      db 12,35,96,55,67
 5 data ends
 6 code segment
 7 start:
 8       ; 補全程式,參考t1.asm,綜合應用以下知識完成:
 9       ; (1) loop指令、記憶體單元地址的靈活表示
10       ; (2) div指令, 數字→數字字元的轉換
11       ; (3) int 21h的2號子功能,完成單個字元輸出的方法,即: 
12       ;     mov ah,2
13       ;     mov dl,待輸出字元或其ASCⅡ碼
14       ;     int 21h
15       ; (4) 資料和資料之間以空格間隔的實現: 使用(3)輸出空格字元
16       
17       mov ax,4c00h
18       int 21h
19 code ends
20 end start

 

補充好的程式碼為:

執行結果:

小結:

此題可認為是任務一的進階,需要輸出的數字更多了,並且增加了輸出空格的要求。不過也不困難,設計一個單層迴圈即可解決。

實驗任務三

要求:根據材料程式設計,在螢幕中間分別顯示綠色、綠底紅色、白底藍色的字串“welcome to masm!”。

材料(摘要):

 

  


 

編寫好的程式碼為:

 

執行結果:

 小結:

 此題做出來也許並不難,難的是追求以一種更簡潔的方式來完成任務。這是我目前想到的比較簡潔的方法,採用了兩層巢狀迴圈。

大體思路:

外層迴圈是bx在不同行之間切換,內層迴圈是si在指定行的某一位置開始依次移動並輸出相應字元。

遇到的困難:

為了把data段的字元傳送到視訊記憶體中,還需要一個指標在這些字元間移動來傳遞字元,初期想讓si身兼兩職,讓si也來充當這個角色,但是發現,視訊記憶體中是用2個位元組來表示一個字元的,即視訊記憶體中的指標是遞增2的,而data段中的指標只需要遞增1,兩者不相容,所以。。。si還是專心當好它視訊記憶體指標的職能吧,我另找了di來作為data段的指標。可是問題又來了,雖然字元傳送的問題是解決了,但是每行字元的屬性都不一樣,我似乎還需要一個指標在這些屬性值間遊走來傳遞屬性值,可是已經沒有額外的指標暫存器可用了。為了最大化利用已有的指標暫存器,只能從尋找規律入手了。發現控制外層迴圈次數的cx是遞減1的,而我們需要的屬性值指標是遞增1的,二者的和應當不變。於是便有了上面的解法。我還是採用di暫存器,因為一行字元的屬性是一樣的,可以在內層迴圈開始之前就將這一行的屬性值設定好,這樣在進入內迴圈的時候di也就被空了出來。