编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串“welcome to masm!”。
已知:内存地址空间中,B8000H~B8FFFH共32KB的空间,为80*25 彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器上。 显示器可以显示25行,每行80个字符(一个字符两个字节),每个字符可以有256种属性。。。
由已知可得:要在屏幕中间显示三行字符串,所在行数分别是 12 13 14 列数我们从33列开始到48列 ;33列对应的单元应该是33*2-2=64 (假设00~01单元对应第一列)
已知:在一行中,一个字占两个字节的存储空间(一个字),低位字节储存字符的ASCII码,高位字节存储字符的属性。一行共有八十个字符,占160个字节。
由已知可得 : 绿色黑底:0000 0010 (02H)
绿底红色:0010 0100(24H)
白底蓝色:0111 0001(71H)
思路:先定位12行第33列 在内存中的位置,然后偏移+1 的内存地址存放字节属性,然后循环16次,从开始的首字母下移一行接着重复上述步骤,直到三行字符串都被写入内存空间。
要点1. 确定首字母的偏移地址=11*160+64=1824 (0720H) ;一行160个字节,此时的段地址默认B800H
要点2. 首字母的位置下移 利用栈结构,先压入栈中,结束循环后再弹出 再把偏移地址+160(00A0H)
下面给出完整的代码
assume cs:codesg,ds:datasg,ss:stacksg
datasg segment
db'welcome to masm!'
datasg ends
stacksg segment
db 16 dup(0)
stacksg ends
codesg segment
start: mov ax,datasg
mov ds,ax
mov ax,stacksg
mov ss,ax
mov sp,16
mov ax,0b800h
mov es,ax
mov si,0
mov bx,1824 ;16进制 0720H
mov cx,16
push bx
s: mov al,ds:[si]
mov es:[bx],al
mov byte ptr es:[bx+1],02h
inc si
add bx,2
loop s
pop bx
add bx,00a0h
mov cx,16
mov si,0
push bx
s1: mov al,ds:[si]
mov es:[bx],al
mov byte ptr es:[bx+1],24h
inc si
add bx,2
loop s1
pop bx
add bx,00a0h
mov cx,16
mov si,0
s2: mov al,ds:[si]
mov es:[bx],al
mov byte ptr es:[bx+1],71h
inc si
add bx,2
loop s2
mov ax,4c00h
int 21h
codesg ends
end start
下面是代码运行结果
错误经验:我160转16进制的时候转成0100h,太蠢了;检查了好久,都没发现,还以为是系统错了。能直接10进制的数字可以直用10进制的数字,转成16进制还要搞错(人工手算),其他能搞对也无所谓。