题目:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串’welcome to masm!’.
分析:根据所给材料可知,DOS全屏模式下,一屏最多可显示内容为80*25个字符,即显示25行,每行80个字符;显存的内存地址空间在B8000H~BFFFFH共32KB的空间处;显示缓冲区分为8页,每页4KB(约4000B),一般显示第0页,即对应的地址为B8000~B8F9F中的4000个字节,显示屏中的字符占两个字节,高字节存放属性,低字节存放要显示的ASCII码,则可推:
偏移000~09F在显示器的第1行 偏移0A0~13F在显示器的第2行 如果要居中显示,则分别占屏幕的12,13,14行,且从每行的第32个字符开始。由于每行占160(A0H)个字符,则可推12行的偏移位置从11*160=6E0H处开始。由于是从每行32个字符开始,则显示的偏移位置还要加上32*2=40H(每个显示字符占两个字节),这样如果要跳到下一行只需偏移位置加160(A0H); 同时由材料中的属性字节格式:BL RGB I RGB : BL 2bit控制闪烁,后面的RGB 3bit控制背景,I 1bit控制高亮,最后的3bit RGB控制前景色可知: 绿色:0 000 0 010B=2H,绿底红色:00 010 0 100=24H,白底蓝色:00 111 0 001=71H.下面说明编写本程序的思路:
(1)设置从12行处开始 (2)读取一种颜色,循环16次依次将每个字符写入当前行数所对应的显存单元中 (3)设置偏移地址加A0H进入一行,重复第2步 这里涉及到了两层循环,外层控制行和颜色,内层控制列显示字符,对应代码如下:
assume cs:codesg,ss:datadata segment db 'welcome to masm!' ; 需要显示的字符数据 db 2H,24H,71H ; 显示的颜色属性值:绿色,绿底红色,白底蓝色data endscodesg segmentstart: mov ax,data mov ss,ax mov bp,0 ; 得到date数据段地址 mov ax,0B800H mov ds,ax mov bx,6E0H ; 得到显存居中的内存地址,从第12开始 mov di,0 mov cx,3 s0: mov ah,ss:[10H+di] ; 得到数据段中颜色属性值 mov dx,cx mov si,0 mov cx,16 s1: mov al,[bp] mov [bx+si+40H],al ; 设置数据段中显示字符,从第32个字符开始 mov [bx+si+41H],ah ; 设置显示颜色属性 add si,2 inc bp loop s1 add bx,0A0H ; 跳转到显存中的下一行 inc di ; 改变di,定位到date段中下一个颜色位置 mov bp,0 mov cx,dx loop s0 mov ax,4C00H int 21H codesg endsend start
则在MS-DOS7.10下运行结果如下: