copen55 发表于 2020-11-18 18:42:05

实验9,根据材料编程实现及陷阱

本帖最后由 copen55 于 2020-11-18 18:42 编辑

实现思路为:1. 三行文字,使用一个循环分三次实现。2. 同时每次循环中,需要将16个字符移动到指定位置以及带上对应的颜色,此时需要一个内层的循环实现16个字符的移动。

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

;定义颜色
;绿色
;绿底红色
;白底蓝色
colorsg segment
        db 2H
        db 24H
        db 71H
colorsg ends

;定义字符串
textsg segment
        db 'welcome to masm!'
textsg ends

stacksg segment
        dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stacksg ends

; 输入文字 B8000H
; 11 12 13 行分别输入
; 中间行: 160*11 = 1760 = 6E0H
; 中间位置: 160 -> 64 + 16*2 + 64
; 64=40H
codesg segment
        ; 缓存区重置
        start:        mov ax,0B800H
                        mov ds,ax
                        mov bx,0

                        mov cx,2000
                        s:        mov ax,0
                                mov ds:,ax
                                add bx,2
                                loop s

        mov ax,0B86Eh                                ; 第11行开始

        ; 必须是一次性刷入内容,否则缓冲区不刷新
        ; mov cx,1                                        ; 一次循环
        mov cx,3                                        ; 三次循环
        mov bp,0                                        ; 颜色下标
        s0:        push cx
                push ax
                push bp       

                mov ds,ax                                 ; 当前行的段地址
                mov bx,40H
                mov ax,textsg
                mov es,ax                                 ; 字符串段

                mov si,0                                ; 中间行 字符位置下标
                mov di,1                                ; 中间行 颜色位置下标
                mov dx,0                                ; 中间行 字符串偏移下标


                mov cx,16                                ; 所有字符循环
                s1:        push bx                         ; 保存偏移到中间位置
                        mov bx,dx
                        mov al,es:                ; 取出字符
                        pop bx
                        mov byte ptr ds:,al        ; 写入字符

                        ; 后面两行
                        ; mov byte ptr ds:,al
                        ; mov byte ptr ds:,al

                        push ds                         ; 保存当前段
                        mov ax,colorsg
                        mov ds,ax                         ; 使用颜色段
                        mov ah,ds:                   ; 颜色
                        pop ds
                        mov byte ptr ds:,ah

                        ; 第二个颜色
                        ; push ds                         ; 保存当前段
                        ; mov ax,colorsg
                        ; mov ds,ax                         ; 使用颜色段
                        ; mov ah,ds:                   ; 颜色
                        ; pop ds
                        ; mov byte ptr ds:,ah

                        ; 第三个颜色
                        ; push ds                         ; 保存当前段
                        ; mov ax,colorsg
                        ; mov ds,ax                         ; 使用颜色段
                        ; mov ah,ds:                   ; 颜色
                        ; pop ds
                        ; mov byte ptr ds:,ah

                       
                        add si,2                        ; 增加计数
                        add di,2
                        inc dx
                        loop s1

                pop bp
                pop ax
                pop cx

                add ax,0A0h                                 ; 移动到下一行
                inc bp
                loop s0

                mov ax,4c00h
                int 21h

codesg ends

end start

但是执行效果只输出一行文字,这是缓冲区不刷新导致的,为了避免这个陷阱,需要一次性写入字符和颜色。

正常输出的一种实现思路:

assume cs:codesg,ds:textsg

;定义颜色
;绿色
;绿底红色
;白底蓝色
colorsg segment
        db 2H
        db 24H
        db 71H
colorsg ends

;定义字符串
textsg segment
        db 'welcome to masm!'
textsg ends


; 输入文字 B8000H
; 11 12 13 行分别输入
; 中间行: 160*11 = 1760 = 6E0H
; 中间位置: 160 -> 64 + 16*2 + 64
; 64=40H
codesg segment
        ; 缓存区重置
        ; 非必要的
        start:        mov ax,0B800H
                        mov ds,ax
                        mov bx,0

                        mov cx,2000
                        s:        mov ax,0
                                mov ds:,ax
                                add bx,2
                                loop s

    mov ax,0B86Eh                                                ; 第11行开始
        mov ds,ax                                                         ; 当前行的段地址
        mov ax,textsg
        mov es,ax                                                         ; 字符串段

        mov bx,colorsg                                                ; 颜色段

        mov si,0                                                        ; 中间行 字符位置下标
        mov di,1                                                        ; 中间行 颜色位置下标
        mov bp,0                                                        ; 中间行 字符串偏移下标
        mov dx,0                                                        ; ds 中间保存寄存器


        mov cx,16                                                        ; 所有字符循环
        s1:        mov al,es:                                        ; 取出字符
                mov byte ptr ds:,al        ; 写入字符
                mov byte ptr ds:,al                ; 64+160 12行
                mov byte ptr ds:,al   ; 64+320 13行

                mov dx,ds                                                 ; 保存当前段
                mov ds,bx
                mov ah,ds:                                           ; 颜色 1
                mov ds,dx
                mov byte ptr ds:,ah

                mov dx,ds                                                 ; 保存当前段
                mov ds,bx
                mov ah, ds:                                        ; 颜色 2
                mov ds,dx
                mov byte ptr ds:,ah

                mov dx,ds                                                 ; 保存当前段
                mov ds,bx
                mov ah, ds:                                        ; 颜色 3
                mov ds,dx
                mov byte ptr ds:,ah

                add si,2                        ; 增加计数
                add di,2
                inc bp
                loop s1

        mov ax,4c00h
        int 21h

codesg ends

end start
页: [1]
查看完整版本: 实验9,根据材料编程实现及陷阱