【跪求帮忙】用汇编语言写的屏保程序,输入任意键后直接退出而非继续屏保

alnessss 2016-07-14 11:37:40
DATAS SEGMENT

left db 0 ;图案位置
right db 79
top db 0
bottom db 24

wait_time db 0 ;进入中断的等待时间
sflag db 0;进入中断后置1,避免同级中断再次发生
direct db 1;方向,1下2上3右4左
count db 0;计数器
tag db 1 ;显示图案的类型

DATAS ENDS


CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
ORG 100H ;强制使得 start 的偏移为0100h
START:
;设置中断向量并驻留程序
INSTALL:

mov ax,datas
mov ds,ax

;set new interrupt vector

mov dx,offset intlc ;偏移地址
mov ax,seg intlc ;段地址
mov ds,ax ;中断向量
mov al,1ch ;中断源为定时器
mov ah,25h ;to set interrupt vector
int 21h ;call DOS,执行intlc

;驻留中断程序

mov dx,offset install ;计算驻留区大小
mov cl,4
shr dx,cl ;右移
add dx,11H ;驻留区大小
mov al,0 ;返回码
mov ah,31h ;驻留程序
int 21h
;中断程序入口
intlc:
sti ;开中断,允许外部中断

mov ax,datas
mov ds,ax

mov al,wait_time
inc al
mov wait_time,al;时间增加,若达到等待时间则进入画图程序
cmp al,91 ;等待时间为5秒
jna continue ;小于零,返回

mov al,sflag ;判断是否有其他中断发生
cmp al,0
jnz continue ;若不为0,即有同级中断在进行则返回

call print ;满足条件,输出

continue:

iret

;改变光标位置,使光标蛇形移动
cursor:
mov ax,datas
mov ds,ax

cmp direct,1;下
jz incdh
cmp direct,2;上
jz decdh
cmp direct,3;右
jz incdl
cmp direct,4;左
jz decdl
jmp exit;判断方向

incdh: ;下
inc dh
cmp dh,bottom
jnz exit;判断位置,到底则返回,继续向下
mov direct,3;方向转为向右
sub bottom,4;下一次移动时则向中心移动
add left,4
add count,1;计数器加1
jmp exit
decdh:
dec dh
cmp dh,top
jnz exit
mov direct,4
add top,4
jmp exit
incdl:
inc dl
cmp dl,right
jnz exit
mov direct,2
sub right,4
jmp exit
decdl:
dec dl
cmp dl,left
jnz exit
mov direct,1
jmp exit
exit:
ret

show:
mov ax,datas
mov ds,ax
call cursor

mov bh,0
mov ah,2 ;置光标位置,第一页
int 10h

mov al,tag ;字符
mov bl,0000111b ;属性 正常显示
mov cx,1 ;字符重复次数
mov ah,9 ;光标位置显示字符及属性
int 10h

call waitf

mov al,00h ;光标位置显示空字符即擦除上一个字符
mov cx,1 ;重复次数
mov ah,0ah ;光标位置只显示字符
int 10h
ret

waitf:;延时
push ax
push cx
mov cx,65500
waitl:;时间延迟
in al,61h
and al,10h
cmp al,ah;
je waitf
mov ah,al
loop waitl

pop cx
pop ax
ret

print:
mov ax,datas
mov ds,ax

;屏幕初始化
mov ah,6
mov al,0;全屏幕为空白
mov bh,7;卷入行属性(黑底白字)
mov ch,0;左上角行号
mov cl,0;左上角列号
mov dh,24;右下角行号
mov dl,79;右下角列号
int 10h

mov al,20h;
out 20h,al;EOI,通知中断结束,可接收中断

mov al,1;置标志位
mov sflag,al;只响应键盘中断

mov dx,0;图案初始位置
next:
call cursor;设置光标位置

cmp tag,6 ;比较符号表示是否为6
jnz nexx
mov tag,0 ;若为6则清零重新开始

nexx:
add tag,1
cmp count,4 ;判断是否已一个周期
jnz nex
mov dx,0 ;复位标志位
mov direct,1
mov count,0
mov left,0
mov right,79
mov top,0
mov bottom,24
nex:
call show
mov ah,1 ;
int 16h ;检测键盘输入
jnz keypressed
jmp next

keypressed:
mov al,0 ;检测到有键盘输入,复位各标志位
mov sflag,al
mov al,0
mov wait_time,al
mov dx,0
;;初始化
mov direct,1
mov count,0
mov left,0
mov right,79
mov top,0
mov bottom,24

ret



CODES ENDS
END START

以上为代码,初学,改了好多天了完全没有起色。求帮忙















...全文
1511 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
baidu_29183065 2016-07-15
  • 打赏
  • 举报
回复
呃... 楼上最后一段代码 mov ah,62h 以下加多一行 int 21h
baidu_29183065 2016-07-15
  • 打赏
  • 举报
回复
代码太多硬伤…. 约略加些片段,仅可达成楼主的意愿。 1.DATAS ENDS之上加四句

old1c_ip dw 0
old1c_cs dw 0 
inDos_off dw 0
inDos_seg dw 0
2. mov dx,offset intlc 之上加如下代码

mov ax,351ch
int 21h
mov old1c_ip,bx
mov old1c_cs,es
mov ah,34h
int 21h
mov inDos_off,bx
mov inDos_seg,es
3. mov bottom,24 至 ret CODES ENDS 中间加如下代码

  mov bottom,24	
;---free memory and reset Interrups
  push es
  push ds
  LES bx,dword ptr inDos_off
  cmp byte ptr es:[bx],0
  jnz quitx
  lds dx,dword ptr old1c_ip
  mov ax,251ch
  int 21h
  push cs
  pop es
  mov ah,49h
  int 21h
  mov ah,62h
  mov es,bx
  int 21h
quitx:
  pop ds
  pop es
  ret

CODES ENDS
 END START
alnessss 2016-07-14
  • 打赏
  • 举报
回复
是的,一段时间后会有字符沿屏幕周围游走
baidu_35605247 2016-07-14
  • 打赏
  • 举报
回复
有邮箱吗?给你发
zara 2016-07-14
  • 打赏
  • 举报
回复
dosbox 下,好像等几秒就有字符沿屏幕周围游走的吗

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧