题目:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串’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:data
data segment
db 'welcome to masm!'
; 需要显示的字符数据
db 2H,24H,71H
; 显示的颜色属性值:绿色,绿底红色,白底蓝色
data ends
codesg segment
start: 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 ends
end start
则在MS-DOS7.10下运行结果如下:


617

被折叠的 条评论
为什么被折叠?



