assume cs:code,ds:data
data segment
db 'Welcome to masm!',0
data ends
code segment
start: mov dh,8 ;dh表示行号(范围:1~25)
mov dl,3 ;dl表示列号(范围:1~80)[注:每超过80等于行号自动加1]
mov cl,2 ;cl中存放颜色属性(0cah为红底高亮闪烁绿色属性)
mov ax,data
mov ds,ax
mov si,0
call show_str
mov ax,4c00h
int 21h
show_str: ;显示字符串的子程序[定义开始]
push cx ;cx和si寄存器后面会用到,防止值被覆盖,先入栈保存
push si
mov al,0a0h ;每行有 80*2 == 160个字节 == 0a0h个字节
;al也就是表示每行有多少个字符
dec dh ;行号在显存中下标从0开始,所以减1。因为计算机内部编号从0开始
mul dh ;dh存放的是行数,dh*al相当于 (n-1)*0a0h。表示从
;第(n-1)*0a0h个Byte单元开始...
;(n-1)*0a0h相乘的结果默认放入ax中
mov bx,ax ;定位好的位置偏移地址存放在bx里(bx定位了行地址)
mov al,2 ;每个字符占两个字节
mul dl ;dl存放列数,定位列,结果ax存放的是定位好的列的位置
sub ax,2 ;列号在显存中下标从0开始,又因为偶字节存放字符,所以减2
add bx,ax ;此时bx中存放的是行与列号的偏移地址
mov ax,0b800h ;显存开始的地址
mov es,ax ;es中存放的是显存的第0页(共0~7页)的起始的段地址
mov di,0 ;di指向显存的偏移地址。指向下一个要处理的字符的位置
mov al,cl ;cl是存放颜色的参数,这时候al存放颜色了
;因为cl下面要用来临时存放要处理的字符
mov ch,0 ;下边cx存放的是每次准备处理的字符
s: mov cl,ds:[si] ;ds:[si]指向“Welcome to masm!”,0
;例如当si=0时,就是把字符W赋给cl。cl存的是W的ASCII码
jcxz ok ;当cl的值为0的时候,cx == 0,则发生跳转,到ok处结束处理!
mov es:[bx+di],cl ;偶地址存放字符
mov es:[bx+di+1],al ;奇地址存放字符的颜色属性
inc si ;si自增1,指向下一个将要处理的字符串中的字符
add di,2 ;指向了下个字符。因为每个字符在显存中占两个字节
jmp short s ;无条件跳转,jcxz是离开的关键跳
ok: pop si
pop cx
ret ;显示字符串的子程序[定义结束]
code ends
end start
执行效果截图:
原文地址:https://www.cnblogs.com/doctorx/p/9696895.html
时间: 2024-10-12 19:50:35