需求:编写子程序,让其通用实现显示以0结尾的字符串。
参数:dh是行,dl是列,cl是颜色属性,ds:si指向字符串首地址
分析:
1.首先,我们要计算出向显存写入的地址。显存位置:B8000H-B8F9FH
算法:(dh-1)*160+dl:就是要写入的偏移地址,而段地址是B800H
2.将颜色属性写入寄存器(如dx)的高位地址,低位地址用来存储字符串
3.我们要向该位置写入字符串,利用jcxz指令判断最后一个字节是否为0,字符串的字节写入寄存器(如dx)的低位地址.
4.完成,返回Ok
以书本中给出的要求为例:在屏幕的8行3列,绿色显示data段中的字符串.
代码如下:
assume cs:code,ds:data,ss:stack
data segment
db 'welcome!',0;定义显示的字符串(16字节)
data ends
stack segment
dw 20 dup(0)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,40
mov dh,12 ;8行
mov dl,64 ;3列
mov cl,02h;绿色
mov si,0 ;指向字符串
call showptr
mov ax,4c00h
int 21h
showptr: ;将用到的寄存器统统存储一遍,后续结束小程序时全部返还
push di
push dx
push cx
push si
push ds
push es
push ax
show:
;将字符串显示在屏幕上,dh是行,dl是列,cl是颜色,ds:si指向字符串首地址
;1.首先计算显存位置
sub dh,1 ;dh减一
mov al,dh ;做乘法运算
mov ah,160
mul ah ;行数减一乘以160 最后将结果ax加上dl即可
mov dh,0
add ax,dx ;ax此时存放写入的地址位置
mov di,ax ;作为显存指针使用
mov ax,0b800h
mov es,ax ;将显存地址写入es
;2.确定颜色属性
mov dh,cl ;将颜色属性赋值高位过去
;3.写入字符串,ds:si指向字符串首地址,需要将字符串存放到dl中
show0:
;这里要利用jcxz了
mov ch,0
mov cl,ds:[si]
jcxz ok
mov dl,ds:[si] ;获取字符串字节
mov es:[di],dx ;将dx写入到es:[di]中去 也就是显存地址
inc si ;字符串指针后移
add di,2 ;显存地址后移
jmp short show0 ;跳转回去
;出口
ok:
pop ax
pop es
pop ds
pop si
pop cx
pop dx
pop di
ret
code ends
end start
奇怪的是,当我向8行3列写入的时候,显示出来怪怪的..而向中间行中间列写入就正常;
如下图:
8行3列的显示效果:
向中间行中间列写入的效果: