|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
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
复制代码
|
|