【虎彡】字符串变色、移动小程序(最终版)
感谢va_zaixuexi大哥shzhfu(牧人)大叔帮我找出了错误所在
感谢圣凡哥让我有了灵感(PS:圣凡哥,3天我就做成了哦~嘿嘿)
感谢 汇编网的移动笑脸让我有了借鉴
首先输入昵称(支持249个字符)回车后无字是因为字是黑色
R变红 B变蓝 G变绿 I高亮 S白底黑字 [L一直变色 按ESC变黑(返回初始)P暂停变色 ][Y键移动 CTRL停止移动并返回(字符停在屏幕中间)] Q退出 “[]”中的按键只在第一个按键后使用(比如ESC、P键只在L键后使用)
整了3天的小程序 收获不小 很有乐趣 在看书之余动手做做小程序(真的很小很小,,)成功后很有成就感
还有些需要改进的,比如回车后看不到字(因为我忘了白字的字符属性了)比如按L一直变色再移动的话变色的位置不变(因为全屏变色太闪眼啦,字符一直变色移动暂时没时间做)
吼吼 下次做个时钟吧! 看到IF汇编和中断纠结了..慢慢消化
(本人知识有限,无编程语言基础、无数学英语基础看王爽老师的书【汇编语言】,第二本 IBM-PC汇编语言看到一半了,第一次自己动手整些小玩意,高手莫笑话)
[align=center][/align]
资源上传无反应 直接上源程序
;*****************************************************************************
data segment
buff db 200,0,200 dup (0)
nam db 'YOUR NAME:$'
one equ 1
count equ 2000
data ends
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov ax,0b800h
mov es,ax
lea dx,nam
mov ah,09h
int 21h ;显示YOUR NAME:
call INPUT_NAME ;调用子程序INPUT_NAME 输入姓名
call xian ;调用子程序在屏幕中间显示字符串
call color ;调用子程序color变色
mov ax,4c00h
int 21h ;看不懂这个你可以果断ALT+F4
;=============================================================================
INPUT_NAME proc near
push ax
push dx
lea dx,buff
mov ah,0ah ;BUFF接收字符可接受200个(包括回车)
int 21h
pop dx
pop ax
ret
INPUT_NAME ENDP
;------------------------------------------
xian proc near
push bx
push cx
push di
push si
mov si,one
mov cl,buff[si]
mov ch,0 ;CX中为输入字符个数
lea bx,buff
add bx,2 ;指向BUFF缓冲区第一个字符
mov di,count ;di指向显存中间
two:
mov al,ds:[bx]
mov es:[di],al ;传送字符
add di,2
inc bx
loop two ;所有存入字符传送到显存中间位置
mov cl,buff[si] ;cl为输入字节数
add cl,0ah ;oah为YOUR NAME:字节数
mov bx,0
qingp:
mov byte ptr es:[bx],' '
add bx,2
loop qingp ;清屏
pop si
pop di
pop cx
pop bx
ret
xian ENDP
;-----------------------------------------
color proc near
push ax
push bx
push cx
xx:
call xian
mov bx,one
mov cx,count
sx:
and byte ptr es:[bx],0 ;颜色清除
add bx,2
loop sx
X:
call xian
mov ah,0
int 16h ;BIOS中断,读取键盘缓冲区
mov ah,1 ;ah=00000001(蓝色)
cmp al,'i'
jz gaol
cmp al,'s'
jz shan
cmp al,'r'
jz red
cmp al,'g'
jz green
cmp al,'b'
jz blue
cmp al,'l'
je bians
cmp al,'q'
jz over
cmp al,'y'
jne agan
call yidong
agan:
jmp x
shan: mov ah,00010000b ;闪烁
gaol: shl ah,1 ;高亮
red : shl ah,1 ;红
green: shl ah,1 ;绿
blue: mov bx,one ;蓝
mov cx,count
s:
and byte ptr es:[bx],01110000b
or es:[bx],ah ;颜色属性写入所有奇地址
add bx,2
loop s
jmp x ;无条件转到X
bians:
mov cx,2
push cx
mov cl,buff[1]
mov ch,0 ;cx取字符个数
mov bx,count+1 ;BX指向显存中间字符位置
bs:
inc byte ptr es:[bx]
add bx,2
loop bs
pop cx ;变色,死循环
in al,60H ;利用60号键盘端口检测ESC键跳出循环
cmp al,01h ;ESC的扫描码
jz xx
cmp al,99h ;P键暂停
jz x
loop bians
over:
pop cx
pop bx
pop ax
ret
color endp
;-------------------------------
yidong proc near
push ax
push bx
push cx
push dx
push si
push di
call qing
mov dx,0 ;光标起始坐标0
kai: push dx ;保护行列DH\DL
MOV AH,2
mov bh,0
int 10h ;调用int 10h第2号中断,置光标
mov cl,buff[1]
mov si,cx
inc si
inc si
mov byte ptr buff[si],'$'
lea dx,buff
add dx,2
mov ah,9
int 21h ;光标位置显示输入的字符串
mov dx,79
sub dx,si
mov cx,dx ;计算列的边界
pop dx ;行列恢复
call delay ;延时
call qing ;清屏(移动准备)
lea si,s2
lea di,s1
cmp dh,24 ;是否大于24行?
jb L ;小于转去比较列
mov ax,cs:[si]
mov cs:[di],ax ;否则DEC DH
L2: cmp dl,cl ;列号是否小于边界
jb L1 ;小于转L
mov ax,cs:[si+2]
mov cs:[di+2],ax ;否则DEC DL
jmp s1
L: cmp dh,0 ;行号是否大于0?
ja L2 ;大于转L2
mov ax,cs:[si+4]
mov cs:[di],ax ;否则inc dh
JMP L2
L1: cmp dl,0 ;列号是否小于0?
ja s1 ;大于转s1
mov ax,cs:[si+6]
mov cs:[di+2],ax ;否则inc dl
s1: inc dh
inc dl
in al,60h ;利用60号键盘端口检测Ctrl键跳出循环
cmp al,1dh ;1DH为CTRL的扫描码
jz qu
jmp kai
s2: dec dh
dec dl
inc dh
inc dl
qu: pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
yidong endp
;--------------------------------
delay proc near
push ax ;空循环(延时)
push dx
mov dx,500h
mov ax,0
s3: sub ax,1
sbb dx,0
cmp ax,0
jne s3
cmp dx,0
jne s3
pop dx
pop ax
ret
delay endp
;----------------------------------
qing proc near
push cx
push bx
mov cx,count
mov bx,0
kong: mov byte ptr es:[bx],' '
add bx,2
loop kong ;清屏
pop bx
pop cx
ret
qing endp
;-----------------------------------
code ends
end start
;*********************************************************************
[解决办法]
祝贺!
[解决办法]
[解决办法]
学习了~~~