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