鱼C论坛

 找回密码
 立即注册
查看: 2462|回复: 0

[汇编作业] 实验9,根据材料编程实现及陷阱

[复制链接]
发表于 2020-11-18 18:42:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 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:[bx],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:[bx]                ; 取出字符
                        pop bx
                        mov byte ptr ds:[bx+si],al          ; 写入字符

                        ; 后面两行
                        ; mov byte ptr ds:[bx+si+160],al
                        ; mov byte ptr ds:[bx+si+320],al

                        push ds                         ; 保存当前段
                        mov ax,colorsg
                        mov ds,ax                         ; 使用颜色段
                        mov ah,ds:[bp]                   ; 颜色
                        pop ds
                        mov byte ptr ds:[bx+di],ah

                        ; 第二个颜色
                        ; push ds                         ; 保存当前段
                        ; mov ax,colorsg
                        ; mov ds,ax                         ; 使用颜色段
                        ; mov ah,ds:[bp+1]                   ; 颜色
                        ; pop ds
                        ; mov byte ptr ds:[bx+di+160],ah

                        ; 第三个颜色
                        ; push ds                         ; 保存当前段
                        ; mov ax,colorsg
                        ; mov ds,ax                         ; 使用颜色段
                        ; mov ah,ds:[bp+2]                   ; 颜色
                        ; pop ds
                        ; mov byte ptr ds:[bx+di+320],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:[bx],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:[bp]                                        ; 取出字符
                mov byte ptr ds:[si+64],al          ; 写入字符
                mov byte ptr ds:[si+224],al                ; 64+160 12行
                mov byte ptr ds:[si+384],al     ; 64+320 13行

                mov dx,ds                                                 ; 保存当前段
                mov ds,bx
                mov ah,ds:[0]                                           ; 颜色 1
                mov ds,dx
                mov byte ptr ds:[di+64],ah

                mov dx,ds                                                 ; 保存当前段
                mov ds,bx
                mov ah, ds:[1]                                        ; 颜色 2
                mov ds,dx
                mov byte ptr ds:[di+224],ah

                mov dx,ds                                                 ; 保存当前段
                mov ds,bx
                mov ah, ds:[2]                                        ; 颜色 3
                mov ds,dx
                mov byte ptr ds:[di+384],ah

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

        mov ax,4c00h
        int 21h

codesg ends

end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 12:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表