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
程序运行示例图