学习<<汇编语言 -王爽>>,自已完成的一道实试题 (2)

实验9 根据材料编程 (材料详见书上188页)


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


材料:

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

  

      内存地址空间中,B8000H~BFFFFH共32KB的空间,该模式下显示器可以显示25行,每行80个字符,每个字符可以有256种属性(背景色、前景色、闪烁、高亮等组合信息)。


      这样,一个字符在显示缓冲区中共占两个字节,分别存放字符的ASCII码和属性。80X25模式下,一屏的内容在显示缓冲区中共占4000个字节。


      显示缓冲区分为8页,每页4KB(约4000B),显示器可以显示任意一页的内容。一般情况下,显示第0页的内容。也就是说通常情况下,B8000H~B8F9FH中的4000个字节的内容将出再在显示器上。


      在一行中,一个字符占两个字节的存储空间( 一个字),低位字节存储字符的ASCII码,高位字节存储字符的属性。一行共点有80个字符,点160个字节。


   属性字节的格式:

二进制位     7       6        5        4        3        2        1        0

对应含义  BL   R    G    B    I    R    G    B

         闪烁     背 景      高亮     前 景


 注意,闪烁的效果必须在全屏DOS方式下才能看到。


以下是我解答的完整的代码:

:>----------------------------------------------------------------------------------------

assume cs: codesg, ds:datasg, ss:stacksg


datasg segment

    db 'welcome to masm!'  ;要显示的数据内容共16个字节

datasg ends


stacksg segment

    dw 0,0,0,0,0,0,0,0  ;这里用栈来保存数据

stacksg ends


codesg segment

   color1: mov ah, 00000010B  ;绿色的字

           jmp ok

   color2: mov ah, 00100100B  ;绿底红字

           jmp ok

   color3: mov ah, 01110001B  ;白底蓝字

           jmp ok

    ;程序入口

    start: mov ax, datasg  

           mov ds, ax

           mov ax, 0B800H

           mov es, ax  ;显存空间段的首地址用es段寄存器保存

           mov di, 0780H  ;用di来在行之间移动,当前di的值为第12行的首地址

           mov cx, 3H  ;要显示3行数据内容,cx=3

       s0: push cx  ;下面有循环嵌套也要用到cx,把它入栈保存,并进入外层循环中

           mov dx, cx  ;dx与外层循环的cx值同步,并用来做比较运算进行不同颜色

                       ; 的配置跳转(即 color1、color2、color3)

           mov si, 0H  ;si与ds结合使用,用来在datasg(ds段中)中取数据,按字节长度逐个取出

           mov bx, 0H  ;bx用来在显示缓存是进行列移动,

                       ; 每次移动两个字节(因为一个字符要显示,要占两个字节)

           mov cx, 10H  ;共处理16个字符

       s1: mov al, [si]  ;将字符的ASCII码值(占一个字节长度)赋给al,并进入内层循环中

           cmp dx, 0003H  ;与3比较是否是第一个要显示的行,即显示绿色的的文字

           jz color1

           cmp dx, 0002H  ;与2比较是否是第二个要显示的行,即显示绿底红字的文字

           jz color2

           cmp dx, 0001H  ;与3比较是否是第三个要显示的行,即显示白底蓝字的文字

           jz color3

       ok: mov es:[bx][di].40H, ax  ;将带有属性字节的显示字符添加到对应的缓存位置

           inc si  ;加1处理下一个要显示的字符

           add bx, 2H  ;加2跳到下一个缓存位置

           loop s1

           

           add di, 0A0H  ;加160(A0H)跳到显存的下一行首地址

           pop cx  ;回到外层循环体,还原cx在外层循环中的值

           loop s0


           mov ax, 4c00H

           int 21H

codesg ends


end start

:<----------------------------------------------------------------------------------------


总结:

   终于可以操作显存控制显示内容了,激动呀!对循环的嵌套还不熟,起初还被我搞成了死循环晕~ ~ ~


-------------   以上的习题部分及代码引用于王爽老师的<<汇编语言>>第二版  ----------------


你可能感兴趣的:(汇编,汇编语言,显示缓冲区,属性字节)