assume cs:code,ds:datadata segment db 'Welcome to masm!',0data endscode segmentstart: 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 21hshow_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 endsend start
执行效果截图: