[048][組合語言]實驗10 3、數值顯示

weixin_34146805發表於2018-04-29

3、數值顯示

10191360-92f62f30ea21292e.png
實驗10 3、數值顯示.png
  • 程式設計,將資料12666以十進位制形式在螢幕的8行3列,用綠色顯示出來。在顯示時我們呼叫本次實驗中的第一個子程式show_str

實際執行

10191360-50be9352dde34d37.png
實驗10 3、數值顯示

完整原始碼

assume cs:code
    data segment
        db 10 dup (0)
    data ends
    
    stack segment
        db 10 dup (0)
    stack ends
    
    code segment
        start:  mov ax,12666
                mov bx,data
                mov ds,bx
                mov si,0
                call dtoc
                
                mov dh,9
                mov dl,3
                mov cl,2
                call show_str
                
                mov ax,4c00H
                int 21H
            
        dtoc:   push ax
                push bx
                push cx
                push dx
                push ds
                push si
                push ss
            
        
                mov dx,0
                mov bx,0AH
                
            s0: mov cx,ax
                jcxz ok0
                div bx
                add dx,30H
                mov ds:[si],dx
                mov dx,0
                inc si
                jmp short s0
        
        ok0:    mov bx,stack
                mov ss,bx
                mov bx,si
        
                mov cx,si
                mov si,0
                s1: push ds:[si]
                    inc si
                    loop s1
                
                mov cx,bx
                mov si,0
                s2: pop ds:[si]
                    inc si
                    loop s2 
                
                mov bx,0
                mov ds:[si],bx
                mov si,bx
                
                
                pop ss
                pop si
                pop ds
                pop dx
                pop cx
                pop bx
                pop ax
                ret
                
        
        
        show_str:   push ax 
                    push es
                    push dx
                    push bx
                    push cx
                    push si
                    push di 
                
                
                    mov ax,0b800h
                    mov es,ax
                    
                    dec dh
                    mov al,160
                    mul dh                  
                    mov bx,ax

                    mov al,2
                    mul dl
                    add bx,ax
    
                    mov dl,cl
                    mov di,0
                    
            show:   mov cl,[si] 
                    mov ch,0
                    jcxz ok
                    mov es:[bx+di],cl
                    mov es:[bx+di+1],dl
                    inc si
                    add di,2
                    jmp short show
                
            ok:     pop di
                    pop si
                    pop cx
                    pop bx
                    pop dx
                    pop es
                    pop ax
                    ret
                
        code ends
        end start

程式碼說明

十進位制碼字元對應的ASCII碼 = 十進位制數碼值 + 30H

  • 12666 是什麼?
十進位制 12666D
十進位制對應的ASCII碼 31H 32H 36H 36H 36H 
十六進位制 317AH (使用16位可以表示)
二進位制  0011 0001 0111 1010B

顯示到螢幕 上要在 【視訊記憶體】 填入 【ASCII碼的值】
要在螢幕上以【十進位制形式】顯示字串
要在【視訊記憶體】填入 【十進位制對應的ASCII碼 31H 32H 36H 36H 36H 】

子程式描述裡提示我們,字串以0結尾符
對應程式碼裡的
    mov bx,0
    mov ds:[si],bx
  • 如何得到每位的值?
被除數/除數=商...餘數
12666 / 10 = 1266...6
1266/10 = 126...6
126/10 = 12...6
12/10 = 1..6
1/10 = 0...1

從餘數得到每位的值
對應程式碼
add dx,30H
mov ds:[si],dx

商為0,作為迴圈終止的判斷條件
對應程式碼
mov cx,ax
jcxz ok0

因為不知道具體的被除數有多少位,
所以只能通過jcxz來進行除法迴圈。

因為得到的餘數依次是6 6 6 2 1,是逆序的, 
所以,用一個棧,將其順序反過來,變成1 2 6 6 6
具體過程就是   6 6 6 2 1 依次進棧,
再按照  1 2 6 6 6的順序依次出棧,直接寫入data段。

  • 使用哪種形式的除法?
直接使用 32位 ÷ 16位 形式的除法
除數 10D = 0AH 被放入16位暫存器 BX
被除數使用 DX(高16位)以及AX(低16位)來表示
餘數和商被放入 DX (餘數)以及 AX(商)

本題中 12666D 本質是 317AH
雖然只用16位暫存器來表示就可以,
但是本題的資料使用16位÷8位的形式會產生溢位,
因此需要使用 32位 ÷ 16位 的形式,
需要將  317AH 擴充套件成 0000 317AH

程式碼參考

相關文章