实验10 编写子程序
2019-07-31 本文已影响0人
耿杰
一、显示字符串
1、问题
显示字符串是现实工作中经常要用到的功能,应该编写一个能用的子程序来实现这个功能。我们应该提供灵活的调用接口,使调用者可以决定显示的位置(行、列)、内容和颜色。
2、子程序描述
- 名称: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
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax, 4c00h
int 21h
show_str:
:
:
code ends
end start
答案
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:
; 利用栈保存调用show_str之前寄存器的值
push ax
push bx
push cx
push dx
push si
push ds
mov ax, 50 ; 显示缓存区每行占用50个字节
dec dh ; sub dh, 1
mul dh ; 第8行,从0开始算就是 dh-1
mov di, ax ; 将 7 * 50的结果保存在di中
mov ax, 2 ; 一个字符在显示缓存区中占2个字节
dec dl ; sub dl, 1
mul dl ; 在第8行的第4个字节。2 * (dl - 1) = 4
add di, ax ; di + ax 就是8行3列的偏移地址
s:
mov ax, cx ; 临时保存cx的值,因为cl保存字符的色值
mov cl, ds:[si] ; 读取data段的字符
mov ch, 0 ; 清空ch的值
jcxz ok ; 判断如果cx的值为0,直接跳转 ok对应的指令
push ds ; 保存ds(data段对应的内存地址)的值
mov cx, ax ; 把ax保存的字符的色值还原到cx中
mov ax, 0B800H ; B800是显示缓冲区的首地址
mov ds, ax
mov ds:[di], bl ; 设置显示的字符
mov ds:[di+1], cl ;设置显示的字符的属性
pop ds ; 把栈顶的data段数据地址还原到ds中
add di, 2 ; 在显示缓冲区中每设置一个新字符,加2
inc si ; 数据段字符读取每次加1
jmp short s
ok:
; 还原成调用show_str寄存器之前的值
pop ds
pop si
pop dx
pop cx
pop bx
pop ax
ret
code ends
end start
结果