汇编语言(王爽第三版)实验9根据材料编程

编程:
       在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串:“welcome to masm!”
程序分析:

       1)在内存中定义并初始化一个字符串:“welcome to masm!”(这个在数据段中定义就可以,使用db)
       2)由材料提示(这里是8位的二进制的组合,形成一个属性)

属性字节的格式:
    7        6        5        4        3        2        1        0
  BL(闪烁)   R(背景)  G(背景)  B(背景)      I(高亮)    R(前景)    G(前景)    B(前景)

              知道:  绿色属性:00000010B==02H

                            绿底红色:00100100B==24H

                            白底蓝色:01110001B==71H

       也就是说02H如果存储在显示缓冲区中的奇数内存单元时,它显示的字符是绿色的。

      3)80x25的彩色字符模式显示缓冲区结构:

内存地址空间中,B8000H~BFFFH共32KB的空间,为80x25的彩色字符模式显示缓冲区,向这个地址写入数据,写入的内容会立即出现在显示器上,在80x25的彩色字符模式下,显示器可以显示25行,每行80个字符,每个字符可以有256种属性(背景色、前景色、闪烁、高亮等组合信息)
这样,一个字符在显示缓冲区就要占两个字节,分别存放字符的ASCII码和属性,80x25模式下,一屏的内容在显示缓冲区共占4000个字节。显示缓冲区分为8页,每页4KB, 显示器可以显示任一页的内容,一帮情况下,显示第0页的内容,也就是说通常情况下,B8000H~B8F9FH中的4000个字节的内容将出现在显示器上

在一页显示缓冲区中:
    偏移000~09F是显示的第一行(80个字符共160个字节)
    偏移0A0~13F是显示的第二行
    偏移140~1DF是显示的第三行
    依此类推,可知,偏移F00~F9F对应显示器上的第25行
题目中由于需要让此字符串(共三行,显示在屏幕中间),共有每页共有25, 故行数应该是在11、12、13行。那么它们的偏移地址的首地址是多少?0640H、06e0H、0780H。(粗略计算,实际上屏幕是多少行也不完全固定的。此处我们不重新计算段地址了,段地址还是B800H,只计算偏移地址。)
"welcome to masm!"字符串有16个字符,也就是说它在显示内存区域中所占空间为32个字节。每行有80个字符显示,那么它在中间显示的话,取中显示,应该在0-159字节中间的第64-96字节(40~60H);也就是在列上偏移40(开始)
行和列的偏移地址确定了。我们就可以试着输出第一行,它的偏移地址是:0640H+0040H=0680H(1664)。我们使用debug在B800:640H处写内存,发现实验成功了。如图。

可以看出在显示缓冲区中偶地址存放字符,奇地址存放字符的颜色属性
       其它剩余2行的偏移地址,我们按照159-31=128计算,即(bx)=(bx)+128.
       字符串和字符的属性是存储在内存的data段中的,如何从内存中将它们(每个字节)取出,然后通过寄存器中转,然后写入到指定的显示缓冲区内(也是内存单元),并指定每个字符的属性(在奇数位置)。
       (es)= (data);(ds)= 0B800H,中转寄存器为ax(按要求将它们分开为2个8位寄存器)。
       由于在屏幕上输出3行“welcome to masm!”,故外循环3次来输出3行,每次一行输出。此为外循环。使用栈来存储CX的状态。
       内循环:将字符和字符属性按照顺序写入到显示缓冲区内。

源代码如下:

assume cs:codesg

data segment
	db 'welcome to masm!'
	db 02h, 24h, 71h
data ends

stack segment
	db 8 dup(0)
stack ends

codesg segment
	    start:mov ax, data
		  mov es, ax
		  mov di, 0
		  
		  mov ax, 0B800h
		  mov ds, ax
		  mov bx, 1664
		  
		  mov si, 16
		  
		  ;建栈,并初始化栈顶
		  mov ax, stack
		  mov ss, ax
		  mov sp, 0
		  
		  mov cx, 3
		  
		s:push cx
		  mov cx, 16
		  
           output:mov al, es:[di]
		  mov ah, es:[si]
		  mov [bx], ax
		  inc di
		  add bx, 2
		  
		  loop output
		  
		  pop cx
		  add bx, 128;偏移量为128字节
		  mov di, 0
		  inc si
		  loop s
		  
		  mov ax, 4100h
		  int 21h
		  
	
codesg ends
end start

输出如图:

也可以把每一行输出的偏移量保存在数据段data中,利用偏移量来取出

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值