汇编笔记-在屏幕中间分别显示绿色,绿底红色,白底蓝色的字符串“welcome to masm!”

; 王爽-汇编语言-第9章
; 完成目标:在屏幕中间分别显示绿色,绿底红色,白底蓝色的字符串“welcome to masm!”
; 其它需要知道的知识点:
; 1. 内存空间中,B8000H-BFFFFH共32KB的空间,为80X25彩色字符模式的显示缓冲区,向这个地址空间写入数据,写入地数据将立架出现在显示器山。
; 1. 显示器显示25行,每行80个字符,每个字符可以有256种属性。
; 2. 一个字符在显示缓冲区就要占两个字节,分别存放字符的ASCII码和属性。
; 3. 一屏的内容在显示缓冲区中共占4000个字节。 80x25=2000
; 4. 一个字节,低位字节存储字符的ASCII码,高位字节存储字符的属性。
; 5. 7 6 5 4 3 2 1 0
; BL R G B I R G B
; 闪烁 背景色 高亮 前景
;
; 6. 如: 黑底绿字: 0000 0010B => 02H
; 闪烁+绿底白字: 1010 0100B => A4H
; 白底蓝字: 0111 0001B => 71H
;
; 7. ‘welcome to masm!’对应的十六进制为:77H, 65H, 6CH, 63H, 6FH, 6DH, 65H, 20H, 74H, 6F, 20H, 6DH, 61H, 73H, 6D, 21H。
; 7. 闪烁的效果必须在全屏DOS下才能看到。(后在DOSBox下实验,不用全屏也能看到效果)
;
; 准备开始完成,进行如下分析:
;
; 1. 本书总的寄存器:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。
;
; 2. 总结寄存器的作用, 准备灵活分配使用寄存器:
;
; ds:数据段; cs:代码段; ss:栈段;
; ip:代码段偏移; sp:栈段偏移
; bx, si, di, bp 寻址变量
; cx: 循环变量
;
; 3. 其它可用的空闲寄存器:
; ax:常给ds赋值; dx:
; es:可用于段前缀
; psw:暂不知道做什么用
;
; 4. 总共35行,那么在中间位置我们用第12,13,14行来显示目标字符串。
; 5. 目标字符串总共16个字符:字母,空格和标点符号。每列显示80个字符,中间显示,我们从每行第32个字符开始显示内容,即第64个字节处开始显示。
; 6. 计算显示字符的位置为:
; 12*160+64 => 1984 => 07C0H
; 13*160+64 => 2144 => 0860H
; 14*160+64 => 2304 => 0900H
; 7. 寄存器分析:
; cx作为行显示3行的行循环和移动字符列循环。es:写入的段寄存器。bx:颜色在数据段的索引。di:每行开始位置在数据段的索引。si:字符在数据段的索引。bp:每个字符具体的显示位置。al:存储字符的ASCII码。ah:存储字符的属性。

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

datasg segment
    db 'welcome to masm!'                       ; 显示的字符
    db 02H, 0A4H, 71H, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0    ; 显示字符的颜色
    dw 12*160+64, 13*160+64, 14*160+64, 0, 0, 0, 0, 0       ; 显示字符开始位置
datasg ends

stacksg segment         ; 定义一个栈段,容量为16个字节
    dw 0,0,0,0,0,0,0,0
stacksg ends

codesg segment
start:
    mov ax, stacksg     ; 设置栈段
    mov ss, ax      
    mov sp, 16

    mov ax, datasg      ; 设置数据段
    mov ds, ax

    mov ax, 0B800H      ; 设置目标段地址,存储写入显示器的数据
    mov es, ax

    mov cx, 3       ; 行索引3
    mov bx, 16      ; 颜色从数据段的16个字节开始
    mov di, 32      ; 显示位置从数据段的32个字节开始

s0: push cx         ; 将外层循环压栈
    mov cx, 16      ; 10H
    mov bp, [di]        ; 初始化显示位置
    mov si, 0

s1: 
    mov al, [si]        ; 低位字节写存储字符的ASCII码
    mov ah, [bx]        ; 高位字节写存储字符的属性
    mov es:[bp], ax

    inc bp
    inc bp          ; 1个字符占用的是2个字节,需要+2
    inc si          ; 下一个显示的字符
    loop s1

    pop cx
    add bx, 1       ; 使用下一个颜色
    add di, 2       ; 下一个显示字符开始位置
    loop s0

    mov ax,4c00H
    int 21H

codesg ends

end start

; 后经测试:
; 1. 若要在左上角显示:那么此值为:1*160+0,意思是从第1行开始计算,不是从第0行开始计算。
; 2. si 作为显示缓冲区偏移地址,如果此值设置为0,将不会有任何显示。

猜你喜欢

转载自blog.csdn.net/chentaoxie/article/details/81267185