汇编实现彩色字符的显示

编程运行环境

选择DOS方式,但现在一般用win10系统,不能进入DOS,只好安装dosbox代替。将写好的源程序保存为asm文件,打开dosbox编译链接并运行。编译链接程序需另行下载,注意与自己的电脑相对应选择32位或64位。

编程目标

在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串’welcome to masm!’。

相关知识

内存地址空间中,B8000H~BFFFFH共32KB的空间即为80×25彩色字符模式显示缓冲区。写入这个地址空间的内容将会出现在显示器上,显示器可以显示25行,每行80个字符,每个字符可以有256种属性
一个字符在显示缓冲区中要占两个字节,偶地址存放字符,奇地址存放字符的属性。通常情况下,B8000H~B8F9FH中的4000个字节的内容将出现在显示器上。

分析

  1. 需要定义存放字符串的内存空间,我们定义数据段来存放字符串,用BX指向其偏移地址。
  2. 我们需要将数据写入显示缓冲区,要取得其段地址,由上述可知该显示缓冲区的段地址为B800H,用es来存放该段地址。
  3. 显示器上的一行80个字符要对应显示缓冲区的160个字节,则行首的偏移地址从0000H开始每行增加A0H。
  4. 在25行80列屏幕中间显示的是3行16列的字符串,则行的偏移地址从6E0H开始,用BP指向行,增量为A0H;列的偏移地址从40H开始,用SI指向列,增量为2。
  5. 我们不难想到用二重循环来解决这个问题,外层循环3次,内层16次循环,需要注意的是每行显示的属性不同,则在外循环中要改变属性存放在寄存器中。具体见源码注释。

源码示例1

assume cs:code,ds:data,ss:stack
data segment
 db 'welcome to masm!'
data ends

stack segment
 db 10 dup (0)
 dw 02H,24H,71H 	;字符的属性:02H为黑底绿字,24H为绿底红字,71H为白底蓝字
stack ends

code segment
start: mov ax,data
	mov ds,ax

	mov ax,stack
 	mov ss,ax
	mov sp,10 	;将栈顶指向堆栈中存放的字符属性

	mov ax,0b800H
 	mov es,ax  	;将显示缓冲区的段地址送入ES
 	mov bp,6e0H 	;BP用来定位显示的行,初始为第11行(从0行记起)

	;AL作为中间变量存放字符的属性,注意栈操作只能为字型数据

	mov cx,3
	s0: mov dx,cx 	;DX暂存外循环变量的值
 	mov bx,0  	;BX用来定位内存的偏移地址
 	mov si,40H 	;SI用来定位显示的列,初始为第64列(从0列记起)
 	pop ax  	;从堆栈中取得字符属性,AL部分有效

	mov cx,16
	s: mov ah,[bx]
 	mov es:[bp][si],ah 	;存放字符的ASCII码
 	mov es:[bp][si].1,al  	;存放字符的属性
 	inc bx
 	add si,2
	loop s

	add bp,0a0H
 	mov cx,dx 	;DX恢复外循环变量的值
 	loop s0

	mov ax,4c00H
 	int 21H
code ends
end start
  1. 汇编源程序的编码安排很灵活,以上程序可以将显示缓冲区的段与存放属性的段相互换。也可以有完全不同的方式,我们需要程序具有修改自身指令并执行的功能,则可以用到几个转移指令。现在我们利用这一点来修改程序数据,详见如下代码。

源码示例2

assume cs:code,ds:data
data segment
 db 'welcome to masm!'
 db 0   	;定义一个值为0的字节用来结束字符串的读取
data ends

code segment
start: mov ax,data
 mov ds,ax
 mov ax,0b800H
 mov es,ax  	;将显示缓冲区的段地址送入ES
 mov bp,6e0H 	;BP用来定位显示的行,初始为第11行(从0行记起)

 mov al,24H 	;AL作为中间变量存放字符的属性
 ; 字符的属性:02H为黑底绿字,24H为绿底红字,71H为白底蓝字
 mov cx,3
s0: mov dx,cx 	;DX暂存外循环变量的值
 mov bx,0  	;BX用来定位内存的偏移地址
 mov si,40H 	;SI用来定位显示的列,初始为第64列(从0列记起)

s: mov cl,[bx]
 mov ch,0
 jcxz s2  	;CX内容的值为零跳转,不为零则继续向下执行
 mov es:[bp][si],cl   		;存放字符的ASCII码
 mov byte ptr es:[bp][si].1,02H  	;存放字符的属性

s1: inc bx
 add si,2
 jmp short s

t: add bp,0a0H
 mov cx,dx 		;DX恢复外循环变量的值
 loop s0

s2: mov di,offset s1
 dec di
 mov cs:[di],al 	;将AL的内容复制到程序中更改字符属性

 mov al,71H 		;修改AL中存放的属性
 jmp short t
code ends
end start

以上程序不必考虑字符串的长度,仅仅关心结束标记,利用转移指令修改源程序的某个数值,要做到的是精确定位。

运行结果

汇编实现彩色字符的显示_第1张图片
编程最重要的还是思想和方法,仔细看这个程序还是有很大缺陷的,关于程序的缺陷以后会详细介绍。

你可能感兴趣的:(汇编语言初级,汇编语言,编程实例,方法技巧)