求助 CPU无效指令 帮我看看哪里错了
题目:设计一个程序完成如下功能:
?初始状态下假设一个字母A或B从屏幕的左下角斜飞出去(速度为每秒钟移动2个字符的位置)
?字母在行进期间碰到屏幕的边沿时反弹。
?使用小键盘对运动中的字母进行控制,小键盘上的按键如下定义:
?4、2、6、8对应左、下、右、上
?1、3、9、7对应左下、右下、右上、左上
?比如:按下9键后字母就向右上方向前进
?程序在按下'ESC'按键时退出。
?要求:
?当字母往前走时必须将前一个字母显示的消除。
?在程序中必须记住当前字母所在的座标、运行方向。屏幕的座标是:行:0-79,列0-24,运行方向可用一个变量表示,该变量从0-7分别表示左、左下、下、右下、右、右上、上、左上
?每次向前移时必须判断下一个座标位置,若碰到边界即X、Y是否为(0、79), (0,24)则进行反弹计算,然后改变运行方向变量值。
?当控制按键按下后除了改变运行方向变量值外还必须判断是否在边界,需要保证下一个字母位置不能有越界的异常情况发生。
DATAS SEGMENT
;此处输入数据段代码
KEY DB 35H
DIR DB 9
X DB 0
Y DB 24
COUNT DB 9
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
;--------------------------------
;Main program
;--------------------------------
main proc far
START:
MOV AX,DATAS
MOV DS,AX
MOV CH,05H
MOV CL,07H
MOV AH,01H
INT 10H
;中断
;保存当前1CH的中断向量,再设置的中断向量
;save old interrupt vector
MOV AL,1CH
MOV AH,35H
INT 21H
PUSH ES
PUSH DX
PUSH DS
;set new interrupt vector
MOV DX,OFFSET DRAW;DX = OFFSET OF DRAW
MOV AX,SEG DRAW;AX = SEGMENT OF DRAW
MOV DS,AX;DS = AX
MOV AL,1CH;AL = VECTOR#
MOV AH,25H;TO SET INTERRUPT VECTOR
INT 21H;CALL DOS
POP DS
IN AL,21H
AND AL,11111110B
OUT 21H,AL
; MOV DI,20000
;DELAY: MOV SI,30000
;DELAY1: DEC SI
;JNZ DELAY1
;DEC DI
;JNZ DELAY
;此处输入代码段代码
LP1:
CMP KEY,27;KEY == ESC
JE EXIT;Y = EXIT
;N
CMP KEY,35H ;KEY == 35H KEY中的值已被取走
JNE DIR_CHECK;N -> DIR_CHECK KEY已有输入 判断原方向的合法性
; Y
;KEY = 键盘按键
MOV AH,07H
INT 21H
CMP AL,35H ;KEY == 5
JE LP1
MOV KEY,AL
SUB AL,30H
;DIR = KEY - 30H
MOV DIR,AL
JMP LP1
;----------------------------------------------;
DIR_CHECK:
LPY0:CMP Y,0;y==0
JNE LPX79;y!=0
CMP DIR,7;dir==7
JB LPX79
MOV AL,DIR;dir>=7
SUB AL,6;dir-6
MOV DIR,AL
LPX79:CMP X,79;x==79
JNE LPY24;x!=79
CMP DIR,9;dir==9
JNE LPY24
CMP DIR,3;dir==3
JNE LPY24
CMP DIR,6;dir==6
JNE LPY24
MOV AL,DIR
SUB AL,2;dir-2
MOV DIR,AL
LPY24:CMP Y,24;Y==24
JNE LPX0;Y!=24
CMP DIR,3;dir==3
JA LPX0
MOV DIR,AL;dir<=3
ADD AL,6;dir+6
MOV DIR,AL
LPX0: CMP X,0;x==0
JNE LPDCE;x!=0
CMP DIR,1;dir==1
JNE LPDCE
CMP DIR,4;dir==4
JNE LPDCE
CMP DIR,7;dir==7
JNE LPDCE
MOV AL,DIR
ADD AL,2;dir +2
MOV DIR,AL
LPDCE:
JMP DCE ;DIR CHECK END
;----------------------------------------------;
EXIT:
;RESTORE OLD INTERRUPT VECTOR
POPDX
POP ES
MOV AL,1CH
MOV AH,25H
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;--------------------------------
;
;
;--------------------------------
DRAW PROC NEAR
PUSH DS
PUSH AX
PUSH CX
PUSH DX
MOV AX,DATAS
MOV DS,AX
;count for print
DEC COUNT
JNZ EXIT_DRAW
JMP DIR_CHECK
DCE:
MOV AL,9
MOV COUNT,AL
CMP DIR,1
JNE CLP1
DEC X
INC Y
JMP CLEAN
CLP1: CMP DIR,2
JNE CLP2
INC Y
JMP CLEAN
CLP2: CMP DIR,3
JNE CLP3
INC X
INC Y
JMP CLEAN
CLP3:CMP DIR,4
JNE CLP4
DEC X
JMP CLEAN
CLP4: CMP DIR,6
JNE CLP5
INC X
JMP CLEAN
CLP5: CMP DIR,7
JNE CLP6
DEC X
DEC Y
JMP CLEAN
CLP6: CMP DIR,8
JNE CLP7
DEC Y
JMP CLEAN
CLP7: CMP DIR,9
JNE CLEAN
INC X
DEC Y
CLEAN:;清屏
MOV AH,6
MOV AL,0
MOV BH,70H
MOV CH,0
MOV CL,0
MOV DH,24
MOV DL,79
INT 10H
;绘图
MOV DH,Y
MOV DL,X
MOV BH,00H
MOV AH,02H
INT 10H
MOV DL,41H
MOV AH,02
INT 21H
;KEY = 35H
MOV AL,35H
MOV KEY,AL
EXIT_DRAW:
POP DX
POP CX
POP AX
POP DS
IRET
DRAW ENDP
CODES ENDS
END START
[最优解释]
不能调试么,先下同个断点,然后再次运行,人离出错最近的断点开始单步。这样死哪了不是一目了然么……
[其他解释]
怎么设断点啊,初学汇编不会用DEBUG啊
[其他解释]
呃……,那就先找点资料看看吧!
你这种都能够运行了的程序出现无效指令,单看源代码是很难看出问题来的……
问题可能出现在指令集版本差异,或者是你的程序跑飞了,不调试真的很难找……
[其他解释]
是不是在代码里插int3,在DEBUG时用-t单步,int3中断了之后程序停在那了,怎么执行过去?
[其他解释]
MOV DS,AX;DS = AX
MOV AL,1CH;AL = VECTOR#
MOV AH,25H;TO SET INTERRUPT VECTOR
INT 21H;CALL DOS
---------------------------------------
我在设置1CH中断这里把上面的注释掉就没CPU无效指令的了,但设置1CH中断要怎么写?
[其他解释]
整个中断准备重写了,看来也没人了。。。。