王爽 匯編語言 第三版 實驗10 編寫子程序


1、顯示字符串


源代碼

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
;功能:在指定的位置,用指定的顏色,顯示一個用0結束的字符串
;參數:(dh)=行號(取值范圍0~24),(dl)=列號(取值范圍0~79),
; (cl)=顏色,ds:si指向字符串的首地址
;返回:無
;---------------------------------------------------------
show_str: ;B800H顯示緩沖區的起始地址,關於顯示緩沖區的問題可以參考實驗9
mov ax,0B800H
mov es,ax

;計算對應行號的起始偏移地址,一行有0A0H個字節(行數 * 0A0H = 偏移地址)
mov al,dh
mov bl,0A0H
mul byte ptr bl
mov bp,ax

;計算對應列號的起始偏移地址,一列有2個字節(列號 * 2 = 偏移地址)
mov ah,0
mov al,dl
add ax,ax
mov di,ax

mov ah,cl ;設置對應的顏色值

;-----------------------------------------------------------------------------------------
;名稱:print
;功能:向屏幕輸出字符
;參數:(si)=偏移地址(字符串段地址 ds),(bp)=從哪一行的偏移地址開始,(顯示緩沖區段地址 es)
; (di)=從哪一列的偏移地址開始,(顯示緩沖區段地址 es)
;返回:無
;-----------------------------------------------------------------------------------------
print: ;取得ds段偏移地址為si的字節數據,並保存到 cl 中
mov ch,0
mov cl,ds:[si]

jcxz ok ;如果cx的值為0,是則跳轉到 ok 標號
mov al,ds:[si] ;將字節數據保存到 al 中
mov es:[bp+di],ax ;輸出到指定的顯示緩沖區位置上

;累加操作
add di,2
inc si
jmp short print

ok: ret
code ends
end start

程序運行示例圖




2、解決除法溢出的問題


源代碼

assume cs:code

code segment
main: mov ax,4240H
mov dx,000FH
mov cx,0AH
call divdw

mov ax,4C00H
int 21h

;------------------------------------------------------------------------------
;名稱:divdw
;功能:進行不會產生溢出的除法運算,被除數為dword型,除數為word型,結果為dword型
;參數:(ax)=dword型數據的低16位
; (bx)=dword型數據的高16位
; (cx)=除數
;返回:(dx)=結果的高16位
; (ax)=結果的低16位
; (cx)=余數
;------------------------------------------------------------------------------
divdw: push ax ;將低16位保存到棧中
;根據公式:X/N = int(H/N)*65536+[rem(H/N)*65536+L]/N
mov ax,dx ;設置ax為高16位
mov dx,0
call doDiv ;跳轉到doDiv執行取得商int()和余數rem()

mov bx,si ;此時的商int()為結果的高16位,先保存到bx寄存器中
pop ax ;從棧中取出低16位設置給ax
mov dx,di ;dx為rem()

call doDiv ;跳轉到doDiv執行
mov dx,bx ;設置結果的高16位
mov ax,si ;設置結果的低16位
mov cx,di ;設置余數
ret

;---------------------------------------
;名稱:doDiv
;功能:兩數相除 取商,取余數
;參數:(ax)=底16位,(dx)=高16位,(cx)=除數
;返回:(si)=商,(di)=余數
;---------------------------------------
doDiv: div word ptr cx
mov si,ax
mov di,dx
ret

code ends

end main


程序運行示例圖


call divdw前



call divdw后



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 dh,8
mov dl,3
mov cl,2
call show_str

mov ax,4C00H
int 21H

;---------------------------------------------------------------
;名稱:dtoc
;功能:將word型數據轉變為表示十進制數的字符串,字符串以0為結尾符
;參數:(ax)=word型數據
; di:si指向字符串的首地址
;返回:無
;---------------------------------------------------------------
dtoc: mov cx,ax
;如果cx為0,則表示除到最后了,跳轉到ok1
jcxz filling
;循環取余數操作,列如ax=12666,依次拿12666,1266,126,12,1去除以10取得余數
mov dx,0
mov bx,10
div word ptr bx

add dx,30H ;余數需進行+30H操作(十進制數碼字符對應的ASCII碼 = 十進制數碼值 + 30H)
push dx ;將數據放入棧中
inc si
jmp short dtoc

;-------------------------------------
;名稱:filling
;功能:向ds段地址(字符串)填充數據
;參數:(si)=數據個數(向棧中取幾次數據)
;返回:無
;-------------------------------------
filling: mov cx,si
mov si,0
a: pop ax
mov ds:[si],al
inc si
loop a
mov ds:[si],cl ;保證字符串以0為結尾符
mov si,0 ;修改為0,保證show_str正確執行
ret

;以下代碼從第一題復制而來
show_str: mov ax,0B800H
mov es,ax
mov al,dh
mov bl,0A0H
mul byte ptr bl
mov bp,ax
mov ah,0
mov al,dl
add ax,ax
mov di,ax
mov ah,cl
print: mov ch,0
mov cl,ds:[si]
jcxz ok
mov al,ds:[si]
mov es:[bp+di],ax
add di,2
inc si
jmp short print
ok: ret
code ends

end start

程序運行示例圖





注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: