1. Display string
名称:show_str
功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串。
参数:(dh)=行号(0-24取值范围),
(dl)=列号(0-79取值范围),
(cl)=颜色(是一个二进制排列组合的值),ds:si指向字符串的首地址
应用举例:在屏幕的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
;cl表示颜色
mov ax,data
mov ds,ax
;段关联
mov si,0
call show_str
mov ax,4C00H
int 21H
show_str: push si
push cx
push es
;保存寄存器值
mov ax,0b800h
mov es,ax
mov al,dh
mul 0A0h
;乘法求行位置
mov bx,ax
;行 bx
mov al,dl
mul 2
;乘法求列位置
mov di,ax
;列 di
mov ah,cl
s: mov al,ds:[si]
mov es:[bx+di],ax
add di,2 ;di表示要显式的偏移地址
inc si ;si表示取数据的偏移地址
mov ch,0
mov cl,al
jcxz ok ;判断是否为0
jmp short s
ok: pop es ;返还
pop cx
pop si
ret
code ends
end start
2. Solve the problem of division overflow
名称:divdw
功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型
参数:(ax)=dword型数据的低16位
(bx)=dword型数据的高16位
(cx)=除数
返回:(dx)=结果的高16位
(ax)=结果的低16位
(cx)=余数
公式: X/N=int(H/N)*62236+[rem(H/N)*65536+L]/N
;十六进制的62236相当于十进制的10000
assume cs:code
code segment
start: mov ax,4240H
mov dx,000FH
mov cx,0AH
call divdw
mov ax,4c00h
int 21H
divdw: push ax
push dx
push cx
push bp
;采用将数据压入栈中而非数据段
;考虑不对调用前的程序的影响
mov ax,dx
mov dx,0
div cx
;除法过后 ax:商 dx:余数
push ax ;将公式前一半算出的数值保存
mov bp,sp
mov ax,[bp+8] ;将原高位值赋给ax
mov dx,0
div cx ;(dx)=rem(H/N)
mov ax,[bp+8]
div cx
push dx ;余数入栈
mov dx,[bp]
pop cx
pop bp
pop bp ;栈退回到bp
ret 6 ;返回ip,并sp+=6
code ends
end start
3. Numerically explicit
名称:dtoc
功能:将word型数据转变为表示十进制数的字符串,字符串以0为结尾符
参数:(ax)=word型数据
di:si指向字符串的首地址
返回:无
应用举例:编程,将数据12666以十进制的形式在屏幕的8行3列,用绿色显示出来。
在显示时我们调用本次实验中的第一个子程序show_str
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
dtoc: push ax
push bx
push si
push cx
s: mov cx,10
div cx
jcxz ok
add cx,30H
mov [bx+si],cx
inc si
jmp short s
ok: pop cx
pop si
pop bx
pop ax
ret
code ends
end start