汇编语言百米赛跑课程设计
;课程设计程序代码:
DATA SEGMENT
NAMES DB 4,?,4 DUP(?)
NAMER DB 4 DUP(?),'$'
RECORDS DB 6 DUP(?),'$'
STRN DB 'Input your name MUST BE 3 WORD:',10,13,'$'
T1 DB 4 DUP(?),'$'
STR1 DB 'Start Game Record Help Exit',10,13,'$' STRH DB 'Press the key panel:LEFT RIGHT LEFT...until WIN',10,13,'$' STRR3 DB 'Ready 3',10,13,'$'
STRR2 DB 'Ready 2',10,13,'$'
STRR1 DB 'Ready 1',10,13,'$'
STRR0 DB 'GO',10,13,'$'
STRW DB 'WIN',10,13,'$'
STRNEW DB 'Play again?Y or N',10,13,'$'
S1 DB 'NAME:',10,13,'$'
S2 DB 'TIME:',10,13,'$'
DATA ENDS
STACK SEGMENT
DW 64 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
MAIN PROC FAR
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX
;-------------------------------
MENU: LEA DX,STR1
MOV AH,09H
INT 21H ;显示菜单
MENU1:MOV AH,0H ;扫描键盘输入
INT 16H
CMP AH,3BH ;3BH是F1的扫描码
JE F1
CMP AH,3CH ;3CH是F2的扫描码
JE F2
CMP AH,3DH ;3DH是F3的扫描码
JE F3
CMP AH,01H ;01H是Esc的扫描码
JE EXITS
JMP MENU1
;-------------------------------
F1: LEA DX,STRN ;提示输入姓名
MOV AH,09H
INT 21H
MOV DX,OFFSET NAMES ;输入姓名
MOV AH,0AH
INT 21H
CALL HUANHANG
V1: CALL READY ;调用ready子过程提示准备
MOV AH,2CH ;调用系统时间开始计时DH:DL=秒:1/100秒
INT 21H
MOV [T1],DH ;将系统时间保存在 T1单元和T1+2单元
MOV [T1+2],DL
CALL RUN ;调用RUN子过程
;------游戏结束提示是否再玩----------
LEA DX,STRNEW
MOV AH,09H
INT 21H
AGAIN: MOV AH,0H ;扫描键盘输入
INT 16H
CMP AH,21 ;21是Y的扫描码
JE V1
CMP AH,49 ;49是N的扫描码
JE MENU
JMP AGAIN
;------显示游戏记录----------
F2: CALL FF2
JMP MENU
;------显示帮助----------
F3: CALL FF3
JMP MENU
EXITS: MOV AH,4CH ;退出 结束
INT 21H
;----------FF2子过程-------------
FF2 PROC
LEA DX,S1
MOV AH,09H
INT 21H
MOV CX,3
LEA SI,NAMES+2 ;将缓冲NAMES的字符移动到NAMER中
LEA DI,NAMER ;NAMES单元是定义的长度,NAMES+1单元系统填充, A5: MOV AL,BYTE PTR[SI] ;而输入的字符串从NAMES+2单元开始存放
MOV BYTE PTR[DI],AL
INC SI
INC DI
LOOP A5
LEA DX,NAMER ;输出NAMER中的名字
MOV AH,09H
INT 21H
CALL HUANHANG
LEA DX,S2 ;输出字符串'TIME:'
MOV AH,09H
INT 21H
LEA SI,T1 ;将T1中的时间转换成ASCII码输出
LEA DI,RECORDS
CALL UBCD2ASC
LEA DX,RECORDS
MOV AH,09H
INT 21H
CALL HUANHANG
RET
FF2 ENDP
;----------FF3子过程-------------
FF3 PROC
LEA DX,STRH
MOV AH,09H
INT 21H
RET
FF3 ENDP
;----------RUN子过程-------------
RUN PROC
MOV CX,49
MOV AH,0H
INT 16H
MOV BL,AH
CMP AH,203
JE L ;如果按下左键则跳到跳到RIGHT比较是不是按的右键
CMP AH,205
JE R ;如果按下右键则跳到跳到LEFT比较是不是按的左键
L: JMP RIGHT
R: JMP LEFT
LEFT: MOV AH,0H ;扫描键盘
INT 16H
CMP AH,BL ;将按下的键与前一次按下的比较
JE LEFT ;相同则重新扫描,不同就将其保存起来
MOV BL,AH ;保存按键方向,准备与再下次的按键比较
JMP RESETR
RIGHT: MOV AH,0H
INT 16H ;与LEFT类似功能
CMP AH,BL
JE RIGHT
MOV BL,AH
JMP RESETL
RESETR: LOOP RIGHT
RESETL: LOOP LEFT
LEA DX,STRW ;提示结束
MOV AH,09H
INT 21H
PUSH DX
PUSH BX
MOV BX,2000 ;设置发声频率
CALL SOUND
POP BX
POP DX
CALL JISHI
CALL FF2
RET
RUN ENDP
;----------提示准备子过程-------------
READY PROC
LEA DX,STRR3 ;输出倒计时字符串
MOV AH,09H
INT 21H
CALL YANSHI ;调用延迟1秒
LEA DX,STRR2
MOV AH,09H
INT 21H
CALL YANSHI ;调用延迟1秒
LEA DX,STRR1
MOV AH,09H
INT 21H
CALL YANSHI ;调用延迟1秒
LEA DX,STRR0
MOV AH,09H
INT 21H
PUSH DX
PUSH BX
MOV BX,2000 ;设置发声频率
CALL SOUND
POP BX
RET
READY ENDP
;----------延时子过程------------
YANSHI PROC
PUSH AX ;保护各个寄存器
PUSH BX
PUSH CX
PUSH DX
MOV DX,0FFFH ;设置双重循环延时
X1: MOV CX,0FFFFH
X2: LOOP X2
DEC DX
CMP DX,0
JA X1
POP DX
POP CX
POP BX
POP AX
RET
YANSHI ENDP
;----------跑步用时子过程-------------
JISHI PROC
PUSH AX
PUSH BX
PUSH DX
MOV AH,2CH ;再次调用系统时间记录结束时间
INT 21H
MOV BH,[T1]
MOV BL,[T1+2]
CMP DL,BL ;不够减则借位减
JNB Q1
SUB DH,1
ADD DL,100
Q1: SUB DL,BL ;将2次时间相减得到跑步时间
CMP DH,BH ;当时间在0秒跨越时,不够减,加60秒
JNB Q2
ADD DH,60
Q2: SUB DH,BH
MOV [T1],DH ;将时间保存在T1中
MOV [T1+2],DL
CALL TO10 ;将T1中存的时间转换成10进制
POP DX
POP BX
RET
JISHI ENDP
;----------回车换行-------------
HUANHANG PROC
MOV DL,0AH
MOV AH,02H
INT 21H
MOV DL,0DH
MOV AH,02H
INT 21H
RET
HUANHANG ENDP
;----------发声---入口参数为BX,BX设置发音的频率----------
SOUND PROC
PUSH AX
PUSH CX
IN AL,61H ;读8255的B端口状态
OR AL,03H ;开PB0,PB1
OUT 61H,AL ;打开扬声器
MOV AL,0B6H ;8253计算器做方波发生器
OUT 43H,AL
MOV AX,34DEH ;基本时钟频率为1.19MHz
MOV DX,12H
DIV BX ;8253的计数初值计算
OUT 42H,AL ;计数处置的送入
MOV AL,AH
OUT 42H,AL
MOV DX,0FFH ;延时
LP: MOV CX,0FFFFH
LL: LOOP LL
DEC DX
CMP DX,0
JA LP
IN AL,61H
AND AL,0FCH
OUT 61H,AL ;关扬声器
POP CX
POP AX
RET
SOUND ENDP
;----------将时间改为对应ASCII码-------------
UBCD2ASC PROC
MOV CX,2;将T1和T1+1单元存的数字转换成ACSII码存放到RECORDS单元中
A1: MOV AL,BYTE PTR[SI]
ADD AL,30H
MOV BYTE PTR[DI],AL
INC SI
INC DI
LOOP A1
MOV AL,2EH ;'.'的ASCII码
MOV BYTE PTR[DI],AL ;将’.’的ASCII码存放到接下来的RECORDS单元中 INC DI
MOV CX,2 ;将T1+2和T1+3单元中的数转换成ASCII码存在接下来的RECORDS单元 A2: MOV AL,BYTE PTR[SI]
ADD AL,30H
MOV BYTE PTR[DI],AL
INC SI
INC DI
LOOP A2
MOV AL,73H ;s的ASCII码
MOV BYTE PTR[DI],AL ;最后将’s’的ASCII码存在接下来的RECORES单元中 RET
UBCD2ASC ENDP
;----------将系统时间转换成10进制-------------
TO10 PROC
PUSH AX ;保护AX BX
PUSH BX
MOV BL,10
MOV AL,[T1] ;取T1中的数转换成10进制
MOV AH,0
DIV BL
MOV [T1],AL ;将转换后的十进制的十位存在T1单元
MOV [T1+1],AH ;将转换后的十进制的十位存在T1+1单元
MOV AL,[T1+2] ;取T1+2中的数转换成10进制
MOV AH,0
DIV BL
MOV [T1+2],AL ;将转换后的十进制的十位存在T1+2单元
MOV [T1+3],AH ;将转换后的十进制的十位存在T1+3单元
POP BX
POP AX
RET
TO10 ENDP
CODE ENDS
END MAIN