实验9
编程: 在屏幕中间分别显示绿色,绿底红色,白底蓝色的字符串'welcome to masm!'
分析:
1
绿色: 0 000 0 010b(二进制) 十六进制 02h
绿底红色:0 010 0 100(二进制)十六进制 24h
白底蓝色:0 111 0 001(二进制)十六进制 71h
2 程序要求在屏幕中间分别显示;
所以效果图应该这样:
***************************************************
* *
* *
* *
* *
* *
*
*
*
*
*
* welcome to masm!
* welcome to masm!
* welcome to masm!
*
*
*
*
*
*
*
* *
* *
* *
**************************************************
因为每行有80个字符,每个字符占2个字节(分别存放ASCIL码和属性,所以每行有160个字节;
所以,'welcome to masm!'共有16个字符所以需要32个字节来存放。
题目中写出:
" 显示缓冲器分为8(0-7)页地址从[B8000H - BFFFFH ,共32KB],在第0页( B8000H - B8F9FH 共占4000字节)显示缓冲区中:
偏移000H-09FH对应显示器上的第1行(80个字符占160个字节A0H个字节);
偏移0A0H-13FH对应显示器上的第2行;
偏移140H-1DFH对应显示器上的第3行;
依此类推,可知,偏移F00 - F9F 对应显示器上的第25行。"
现在,我们要把 'welcome to masm!' 写在第0页中,当然也可写在其它页(0 - 7 )页都可以
现在我们要写在第0页中。第0页地址从 B8000H - B8F9FH 共占4000字节而我们的需要把三行写到40000个字节的中间!
所以这个起始地址为 (4000-3*160)/2=1760 ==> 1760+(160-32)/2=1824 = 720H + B8000H = B8720H
地址为:B8720H 段地址表示为: B872H:0000H
现在可以开始写代码:
assume cs:code,ds:data
data segment
db 'welcome to masm!'
data ends
code segment
start: mov ax,data
mov ds,ax
mov ax,0B872H
mov es,ax
mov di,0
mov si,0
mov cx,16
s: mov al,[di] ;循环16次把welcome to masm!复制到3行
mov es:[si],al
mov es:[si+0A0H],al
mov es:[si+140H],al
add si,2
inc di
loop s
mov si,1
mov cx,16
s0: mov al,02h ;循环16次修改它们的色彩属性
mov es:[si],al
mov al,24h
mov es:[si+0A0H],al
mov al,71h
mov es:[si+140H],al
add si,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
精炼的代码
assume cs:code
data segment
db 'welcome to masm!' ;定义要显示的字符串(共16字节)
db 02h,24h,71h ;定义三种颜色属性
data ends
code segment
start: mov ax,data
mov ds,ax
;这不用解释吧?
mov ax,0B800h
mov es,ax
;那什么显示缓冲区的段地址
mov bx,0
mov si,0
mov cx,10h
s: mov al,ds:[bx]
;取出字符,放到AL中。
mov ah,ds:[10h];取出颜色,放到AH中。
mov es:7c0h[si],ax
;显示字符
mov ah,ds:[11h];取出颜色,放到AH中。
mov es:860h[si],ax
;显示字符
mov ah,ds:[12h];取出颜色,放到AH中。
mov es:900h[si],ax
;显示字符
inc bx
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start