彙編實驗十(王爽)

設計子程序oop

子程序一:在指定的位置,用指定的顏色,顯示一個用0結束的字符串spa

舉例:在屏幕的8行3列,用綠色顯示data段中的字符串設計

assume cs:code

data segment
    db 'Welcome to masm!',0
data ends

code segment
start:   mov dh,8     ;行
         mov dl,3     ;列
         mov cl,2     ;顏色屬性
         mov ax,data
         mov ds,ax
         mov si,0
         call show_str  ;子程序

         mov ax,4c00h
         int 21h

show_str:
         push dx   ;避免寄存器衝突(雖然這個子程序沒有衝突,但爲了更好的使用,仍是加上了)
         push cx
         push si  
        
         mov ax,0b800h  
         mov es,ax   ;顯示緩衝區段地址
         mov al,dh
         mov bl,0a0h  ;用於計算第八行的首地址
         dec al      
         mul bl    ;首地址在ax中
         mov bx,ax  ;存在bx寄存器內
         mov dh,0
         mov di,dx  ;用於計算列地址
         dec di
         add di,di ;列地址就在di寄存器中
         mov al,cl
      s: mov cl,ds:[si] ;取出字符,要判斷cx是否爲0
         mov ch,0
         jcxz ok  ;終止指令跳轉的條件
         mov dl,ds:[si]   ;取出字符
         mov es:[bx+di],dl   ;將字符送入顯示緩衝區中
         mov es:[bx+di+1],al  ;設置字符屬性
         inc si     ;data段的地址偏移+1
         add di,2   ;顯是緩衝區段地址+2
         jmp short s ;指令跳轉

     ok: 
         pop dx  ;恢復主程序中寄存器的值
         pop cx
         pop si
         ret   ;子程序返回
code ends

end start

 

運行結果:(不知明緣由,第一行會被吃掉,所以實際顯示是在第七行)3d

 

 

子程序二:code

功能:解決除法溢出問題blog

應用舉例:計算1000000/10(F4240/0AH)內存

返回: (dx) = 結果的高16位,(ax)=結果的低16位,(cx)=餘數ci

結果:(dx) =0001H, (ax)=86A0H,(cx)=0 rem

公式:字符串

H:X的高16位

L:X的低16位

N:除數

X/N = int(H/N)*65535 + [rem(H/N*65535)+L]/N

(對公式的理解很重要!!!我看了半天,纔看懂了)

 

assume cs:code


code segment
start:  mov ax,4240h  ;存放被除數(dword類)的低16位地址
        mov dx,000fh   ;存放被除數(dword類)的高16位地址
        mov cx,0ah     ;存放除數
        call divdw

divdw: 
        push ax   ;把ax(即低16位地址先存入棧中,以後要用到)

        mov ax,dx  ;對高16位地址進行16位除法
        mov dx,0
        div cx
        mov bx,ax ;bx的值爲int(H/N),將除法所得商移入bx中
        pop ax    ;取出低16位地址
    
div cx ;對低16位地址進行16位除法,結果的低16位商位於ax寄存器中 mov cx,dx ;將餘數移入cx中 mov dx,bx ;將結果的高16位商移入dx中 ret code ends end start

 

 運行結果:

 

 子程序設計三:

功能:將word型數據轉變爲表示十進制數據的字符串,字符串以0結尾

應用舉例:將12666以十進制的形式在屏幕的8行3列,用綠色顯示出來(顯示時調用子程序一)

assume cs:code

data segment
    db 10 dup(0) ;保存字符串的內存地址段
data ends


code segment
start:      mov ax,12666
            mov bx,data
            mov ds,bx
            mov si,0
            call dtoc  ;調用子程序

            mov ax,4c00h
            int 21h

dtoc:       mov bx,10   ;bx爲除數
            mov dx,0    
            div bx    ;對ax進行16位除法
            mov cx,ax  ;商保存在cx中,用於結束除法的繼續,當商爲0時,表明全部餘數已求出
            add dx,30h ;利用十進制對應的ascii碼=十進制數值碼+30H,得出字符並存在寄存器dx中
            push dx   ;將字符結果保存在棧中,由於餘數結果相對於自己字符的順序是逆序,所以咱們要利用棧來逆序
            add si,1  ;記錄除的次數,也就是字符的個數
            jcxz s1  ;若cx即商爲0,則調到s1處
            jmp short dtoc  ;循環除法

            
s1:         mov bl,0
            mov ds:[si],bl  ;在data段的即將放入字符的末尾,將0存入
            mov cx,si  ;將字符的個數存取cx中
            mov si,0   ;si寄存器表示data段的偏移地址
s2:         pop ds:[si] ;取出放在棧中的數據
            add si,1   ;偏移地址+1
            loop s2  ;循環

            mov dh,8  ;顯示字符串
            mov dl,3
            mov cl,2
            mov si,0
            call show_str
            ret

show_str:    push dx
             push cx
             push si  
            
             mov ax,0b800h
             mov es,ax
             mov al,dh
             mov bl,0a0h
             dec al
             mul bl
             mov bx,ax
             mov dh,0
             mov di,dx
             dec di
             add di,di
             mov al,cl
          s: mov cl,ds:[si]
             mov ch,0
             jcxz ok
             mov dl,ds:[si]
             mov es:[bx+di],dl
             mov es:[bx+di+1],al
             inc si
             add di,2
             jmp short s

         ok: 
             pop dx
             pop cx
             pop si

             ret
code ends

end start

運行結果:(仍是同樣,第一行顯示的會被吃掉,因此實際在第七行)

相關文章
相關標籤/搜索