目录
前言
本文主要内容是王爽老师《汇编语言》(第四版)第九章 实验9 “根据材料编程” 任务的分析以及实现代码。
一、题目
在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串“welcome to masm!”。
二、分析
1.程序结构分析
(1)要显示的字符串应该用单独的一段空间来存储,我的方法是专门写一个data段,并开辟16个字节型数据的空间。如下。
data segment
db "welcome to masm!"
data ends
(2)每一个字符占2个字节的存储空间,其中一个字节用来存储属性。那么这个表示属性的字节数据,应该是反复用到的,那就应该存储在内存中,而不应该在程序中用寄存器存储。而且,题目要求一共要显示三种不同属性的字符,也就是说,这个表示属性的字节应该方便更改。考虑到以后也可能有更多的需求,比如显示5种不同属性的字符,于是我的方法就是,在data段中再开辟一段空间,用于存储表示属性的字节。
绿色字符 对应的属性字节是0000 0010 B,对应的16进制是02H;
绿底红色字符 对应的属性字节是0010 0100 B,对应的16进制是24H;
白底蓝色字符 对应的属性字节是0111 0001 B,对应的16进制位71H。
data segment
db "welcome to masm!"
db 02H,24H 71H
data ends
(3)第一屏的内容所对应的内存地址空间为B8000H~B8F9FH,因而可以令这一段的段地址为B800H。
2.字符位置
题目要求将字符显示在屏幕中间,而一屏共25行,每行80个字符。由此可知,字符应该从第12(从0开始计数)行第32(从0开始计数)个字符开始显示。也就是从第1984个字符(从0开始)开始显示,16进制为07C0H。
3.代码
assume cs:code,ds:data
data segment
db 'welcome to masm!' ;要显示的字符串
db 02H,24H,71H ;三种属性的属性字节
data ends
code segment
start:
mov ax,0B800H ;设置es段地址,指向要显示缓冲区
mov es,ax
mov ax,data ;设置ds段地址,指向data段
mov ds,ax
mov bx,0000H ;data段中数据的偏移地址,指向当前要显示的那个字符
mov si,07C0H ;es段中的数据的偏移地址,指向当前要在缓冲区哪个地址显示出字符
mov di,10H ;data段中数据的偏移地址,指向当前使用的属性字节
mov cx,16 ;每次从data段中复制数据到缓冲区,要复制16个字符,因此循环16次
s:
mov al,ds:[bx] ;将字符字节复制到缓冲区
mov es:[si],al
inc si ;指向缓冲区下一个字节
mov al,ds:[di] ;将属性字节复制到缓冲区
mov es:[si],al
inc bx ;指向data段与缓冲区的下一个字节
inc si
loop s
mov ax,4c00H ;程序返回
int 21H
code ends
end start
以上代码显示的是第一种属性的字符,即绿色字符。如果要显示第二种属性的字符(绿底红色),只需要将di修改一下即可,简单方便。这就是使用变量的好处。代码如下。
assume cs:code,ds:data
data segment
db 'welcome to masm!'
db 02H,24H,71H
data ends
code segment
start:
mov ax,0B800H
mov es,ax
mov ax,data
mov ds,ax
mov bx,0000H
mov si,07C0H
mov di,11H ;这里修改一下
mov cx,16
s:
mov al,ds:[bx]
mov es:[si],al
inc si
mov al,ds:[di]
mov es:[si],al
inc bx
inc si
loop s
mov ax,4c00H
int 21H
code ends
end start
三、1024节日快乐
今日恰逢1024,于是学习之余顺道给自己写个小玩意儿,以表庆祝!效果如下。
代码如下。
assume cs:code,ds:data,ss:stack
data segment
db " * **** **** * * "
db " * * * * * * "
db " * * * * * * "
db " * * * **** **** "
db " * * * * * "
db " * * * * * "
db " * **** **** * "
db 32 dup(" ")
db " celebrity!! "
db 1AH ;字符属性字节
data ends
stack segment
dw 0
stack ends
code segment
start:
mov ax,0B800H ;设置段地址
mov es,ax
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,10H
mov bx,0000H ;data段偏移地址
mov si,048EH ;显存区es段偏移地址
mov di,0120H ;字符属性字节所在的偏移地址
mov cx,9 ;外循环次数(字符显示行数)
s0:
push cx
mov cx,32 ;每行显示32个字符
s:
mov al,ds:[bx] ;显示当前字符
mov es:[si],al
inc si
mov al,ds:[di] ;显示当前字符的属性
mov es:[si],al
inc bx
inc si
loop s
add si,0060H ;显存区偏移地址切换到下一行
pop cx
loop s0
mov ax,4c00H ;程序返回
int 21H
code ends
end start
总结
本文介绍了王爽老师《汇编语言》(第四版)第九章 实验9 的题目分析以及实现代码。最后给自己写了个小程序,作为1024节日庆祝礼。