實驗 9 根據材料編程

1、實驗目的

1. 掌握十進制兩位數輸出的方法編程

2.  理解 80×25 彩色字符模式顯示原理框架

3. 綜合應用尋址方式和彙編指令完成應用編程oop

 

2、實驗準備

1.  複習數值和數字字符之間的轉換方法,div 指令用法學習

2.  學習 P187-189 支撐材料及「實驗 9 提示」(本文檔最後一部分)優化

3.  複習靈活的尋址方式及本次實驗中用到的指令,如 mov, loop,div 等。spa

 

3、實驗內容

1.  補全程序 t1.asm,完成在屏幕上輸出內存單元中的十進制兩位數設計

(1)在程序框架中補全代碼以下:code

(2)分析:第一個空顯然的須要將data段地址放到ds中,經過ax寄存器兩條指令blog

mov ax,data內存

mov ds,ax來實現便可;

第二個空,須要將被除數12,即段地址爲ds,偏移地址爲0的內容送到寄存器ax中,

ax是16位寄存器,因此應該應該放入低8位AL寄存器中。

接下來一個空同上,按照提示,將商12保存到註釋中指定單元,即偏移地址爲1的數據段

mov dl,ds:[1]

接下來一個空須要將數值轉換爲數字字符,根據ASCII碼,數字字符與相應的數字之間相差48,

也就是30h。因此只要使用add命令加上30h就好了。

最後兩個空其實也是同上的,餘數在偏移地址爲2的數據段(ds:[2]),最後一個空同理,加上48(30h)

數值變成數字字符。

(3)代碼執行結果以下:

 

2. 補全程序 t2.asm,完成在屏幕上輸出 data 段定義的 5 個十進制兩位數,數據和數據 之間以空格間隔。

(1)補全代碼以下:

(2)分析:

 第一處參考t1.asm的內容可知,須要將data表示的段地址送到ds中,經過

mov ax,data

mov data,ds

來實現

由於這裏確定須要用到循環,因此cx = 5,有五個數表示循環五次,bx初值爲零

顯而易見是爲了用[bx]方便表示偏移地址從0到5,inc bx在循環中依次遞增;

 

下面咱們就進入了loop循環階段

咱們先來探討一下如何輸出一個字符,不急着寫。

題目要求的是輸出五個數,每一箇中間隔有空格。

mov ah,2
mov dl,待輸出字符或其ASCⅡ碼
int 21h

根據提示這個格式是用來輸出字符的,因此說咱們要執行的五次循環是每次循環按順序輸出一個數再加一個空格

首先這個空格是很好輸出的,經查詢空格的ASCII碼是32(即20h),因此在這個loop循環的末尾處先寫上這個代碼

mov ah,2

mov dl,20h

int 21h

inc bx

loop s

後面的inc bx,loop s顯然不用解釋了,inc bx每次加一,靈活表示內存地址,這樣咱們能夠按順序依次取一個數。

 

如今程序的末尾咱們已經寫好,空格已經能夠輸出,接下來只要在循環中輸出五個數便可

如何作到?彷佛按照提示,咱們只須要找的這五個數的ASCII碼就好了,但這五個數都是兩位數,

顯然ASCII碼中的數字是設置了0到9的,對於兩位數,咱們沒法直接找到它的ASCII碼。

那麼咱們能夠換個思惟,一個數拆成兩份,個位數和十位數,咱們分別輸出就好了。

如何將一個兩位數拆成個位數和十位數分開,在C語言中咱們有過不少這樣的題目,只要讓這個數除以10能夠獲得它的十位數,

再用%運算就能獲得它的個位數。在彙編語言中甚至不用這麼麻煩,只要用div命令,咱們就能夠同時的到它的商(即兩位數的十位數)和餘數

(即兩位數的個位數),其中商放在al中,餘數放在ah中,再用

mov ah,2
mov dl,待輸出字符或其ASCⅡ碼
int 21h

分別按順序輸出商和餘數便可。

 

分析道這裏已經很清楚了,循環的開始先要將ax置爲0,把除數10放在dl中。後面的程序具體細節就再也不贅述。

但仍然須要注意t1.asm中已經提過的,咱們獲得的餘數和商都是一個數值,咱們所能輸出的是數字字符,按照ASCII碼中二者相差48(30h)

,咱們加上便可。

固然還須要解釋一點,可能有人會以爲按照

mov ah,2
mov dl,待輸出字符或其ASCⅡ碼
int 21h

的格式才能輸出字符,爲何咱們的上述代碼中,商的輸出是用add dl,30h的

,事實上add的做用很明顯是相加後再送回,因此實際上送回的那一步包含在內了。

 

(3)實驗結果以下:

 顯然實驗成功

3.  教材實驗 9(P187)

在屏幕中間分別顯示綠色、綠底紅色、白底藍色的字符串’welcome to masm!'

 代碼以下:

; p187 實驗9

assume ds:data, cs:code, ss:stack
data segment
       db 'welcome to masm!'  
       db 2H,24H,71H          ;字符串屬性值
data ends
stack segment
       db 2 dup(0)
stack ends
code segment
start:  mov ax,stack
        mov ss,ax
        mov sp,0

        mov ax,data
        mov ds,ax            ;字符串及屬性值所在段的段地址送入ds
        
        mov ax,0b800H
        mov es,ax            ;80×25彩色字符模式顯示緩衝區段地址送入es
        
        
        mov si,0                ; 每次循環後,es:[bx],bx應該+2,bx沒法+2,靠si輔助 
        mov di,0                ; di控制顏色屬性
        
        mov cx,3                ; 外層循環
s0:     push cx                 ; cx暫存

        mov bx,0                ; bx控制字符獲取,每次向後獲取一位

        mov cx,16               ; 控制循環次數
s:      mov al,ds:[bx]
        mov es:[bx+si], al      ; 待顯示字符送入顯存單元b800:0
        mov ah,ds:[di+16]
        mov es:[bx+si+1], ah    ; 待顯示字符顏色屬性(綠色)送入顯存單元b800:1   
        inc si
        inc bx
        loop s
        
        add si,144              ;換行
        inc di
        pop cx                  ;暫存的cx取出
        loop s0
        ; 添加代碼,經過循環逐個將每一個字符及其屬性送入相應的顯示緩衝區對應行
        ; 即:將data段的字符及屬性經過循環逐個mov到顯示緩衝區(es)段相應的單元內
        
        ; 能夠先嚐試分別寫三段代碼,每次完成一行的顯示
        ; 程序運行起來後,再嘗試經過靈活的尋址方式和循環,對三段代碼修改和簡化
        ; 學習第10章子程序後,還能夠進一步完善優化,設計子程序,將行號、列號、顏色屬性設置成入口參數
        

        mov ax,4c00h
        int 21h
code ends
end start

(2)分析:

咱們要輸出的是兩行字符串,而每一行字符串實際上在前面的實驗中也已經說過,只能逐個輸出,這樣以來咱們就要設置內存循環和外層循環。

內存循環用來逐個輸出字符,這條字符串共有16個字符,因此在這裏咱們須要設置cx = 16;外層循環用來控制換行,輸出不一樣顏色的。

根據書中的知識在一行中,一個字符佔兩個字節的存儲空間,低位字節存儲字符的ASCII碼,高位字節存儲字符的屬性。因此bx每次要加2,須要si的幫助來實現。

(3)運行結果如:

4、總結

(1)經過這次實驗,練習掌握了div命令的操做以及掌握十進制兩位數輸出的方法。

(2)彙編語言的學習使咱們對以前所學習的高級語言有了一個更深的理解。

相關文章
相關標籤/搜索