简单x86四则计算练习程序 汇编实现
DATA SEGMENT OP DB ? NUM1 DW ? NUM2 DW ? ANSWER DW ? SPA DB 36 DUP(20H) STRING DB 20 DUP(?) FLAGE DW 0 PASS DW 0 TOTAL DW 0 RESULT DB 29 DUP(20H),'Your accuracy is ' RATE DB 10 DUP(20H) BYE DB 0DH,0AH,0DH,0AH,20 DUP(20H),'Thank you for using our system. Goodbye!','$' TIPS1 DB 80 DUP(2AH),2AH,78 DUP(20H),2AH,2AH,78 DUP(20H),2AH,2AH,16 DUP(20H) DB 'Welcome To Use Calculations Training System!',18 DUP(20H),2AH DB 2AH,78 DUP(20H),2AH,2AH,78 DUP(20H),2AH,80 DUP(2AH),0DH,0AH,'$' TIPS2 DB 'Press any key to practice and press SPACE to quit.',0DH,0AH,0DH,0AH,'$' TIPS3 DB 0DH,0AH,'Press any key to continue and press SPACE to finish the exercise.',0DH,0AH,0DH,0AH,'$' RIGHT DB 160 DUP(20H),19 DUP(20H),'Congratulations, your answer is correct!',0DH,0AH,'$' WRONG DB 160 DUP(20H),12 DUP(20H),'Sorry, your answer is wrong! The correct answer is ' ANS DB 8 DUP(20H) DATA ENDS STACK SEGMENT PARA STACK 'STACK' STA DB 80 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK START PROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV AX,03 ;清屏 INT 10H ;以下为改变字符颜色代码 MOV CX,560 MOV AH,09 LEA BX,TIPS1 DISP1: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,10011100B ;蓝底红字闪烁 MOV CX,560 INT 10H POP CX POP BX INC BX LOOP DISP1 LEA DX,TIPS1 CALL DISPLAY ;显示欢迎语 LEA DX,TIPS2 CALL DISPLAY ;显示提示 MOV AH,07 INT 21H ;等待用户选择 CMP AL,20H ;输入是否为空格 JE QUIT ;是则退出程序 RE: MOV BX,04 CALL RAND ;产生一个到之间随机数 CMP AL,01 JE MPLUS ;若产生了则生成加法式 CMP AL,02 JE MMINUS ;若产生了则生成减法式 CMP AL,03 JE MMULT ;若产生了则生成乘法式 CALL DIVIDE ;若为则直接调用除法子程序 JMP OUTP MPLUS: CALL PLUS ;调用加法子程序 JMP OUTP MMINUS: CALL MINUS ;调用减法子程序 JMP OUTP MMULT: CALL MULT ;调用乘法子程序 JMP OUTP OUTP: CALL INPUT ;调用用户输入结果子程序 LEA DX,TIPS3 CALL DISPLAY MOV AH,07 INT 21H ;等待用户选择 PUSH AX MOV CX,0A00H MOV DX,124FH MOV BH,07H MOV AX,0609H INT 10H ;将部分屏幕内容清除 MOV AH,02H MOV BH,0 MOV DX,0A00H INT 10H ;重置光标位置 POP AX CMP AL,20H ;输入是否为空格 JNE RE ;不是则继续产生算式 CALL ACCUR ;是空格则调用计算正确率子程序 LEA DX,BYE CALL DISPLAY MOV AH,07 INT 21H ;按任意键退出本程序 QUIT: RET START ENDP ;-------------产生随机数子程序------------- RAND PROC NEAR MOV AX,BX MOV DX,41H ;用中断计时器的H端口 OUT DX,AX ;产生到BX值之间的随机数 IN AL,DX ;将随机数送到AL RET RAND ENDP ;----------------加法子程序---------------- PLUS PROC NEAR MOV BX,99 ;在到之间产生第一个加数 CALL RAND MOV AH,0 MOV NUM1,AX ;将第一个加数存到NUM1 CALL RAND ;在到之间产生第二个加数 MOV AH,0 MOV NUM2,AX ;将第一个加数存到NUM2 MOV BX,NUM1 ADD AX,BX ;相加 MOV ANSWER,AX ;将和送到ANSWER MOV OP,'+' CALL CHANGE ;以下为改变字符颜色代码 MOV CX,79 MOV AH,09 LEA BX,SPA DISP2: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001010B ;黑底绿字 MOV CX,79 INT 10H POP CX POP BX INC BX LOOP DISP2 LEA DX,SPA CALL DISPLAY RET PLUS ENDP ;----------------减法子程序---------------- MINUS PROC NEAR MOV BX,99 CALL RAND ;在到之间产生差 MOV AH,0 MOV ANSWER,AX ;将差存到ANSWER CALL RAND ;在到之间产生减数 MOV AH,0 MOV NUM2,AX ;将减数存到NUM2 MOV BX,ANSWER ADD AX,BX ;将差与减数相加得到被减数 MOV NUM1,AX ;将被减数存到NUM1 MOV OP,'-' CALL CHANGE ;以下为改变字符颜色代码 MOV CX,79 MOV AH,09 LEA BX,SPA DISP3: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001010B ;黑底绿字 MOV CX,79 INT 10H POP CX POP BX INC BX LOOP DISP3 LEA DX,SPA CALL DISPLAY RET MINUS ENDP ;----------------乘法子程序---------------- MULT PROC NEAR MOV BX,99 ;在到之间产生第一个乘数 CALL RAND MOV AH,0 MOV NUM1,AX ;将第一个乘数存到NUM1 CALL RAND ;在到之间产生第二个乘数 MOV AH,0 MOV NUM2,AX ;将第一个乘数存到NUM2 MOV BX,NUM1 MUL BX ;相乘 MOV ANSWER,AX ;将积送到ANSWER MOV OP,'*' CALL CHANGE ;以下为改变字符颜色代码 MOV CX,79 MOV AH,09 LEA BX,SPA DISP4: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001010B ;黑底绿字 MOV CX,79 INT 10H POP CX POP BX INC BX LOOP DISP4 LEA DX,SPA CALL DISPLAY RET MULT ENDP ;----------------除法子程序---------------- DIVIDE PROC NEAR MOV BX,99 ;在到之间产生商 CALL RAND MOV AH,0 MOV ANSWER,AX ;将商存到ANSWER CALL RAND ;在到之间产生除数 MOV AH,0 MOV NUM2,AX ;将除数存到NUM2 MOV BX,ANSWER MUL BX ;将商与除数相乘得到被除数 MOV NUM1,AX ;将被除数送到NUM1 MOV OP,'/' CALL CHANGE ;以下为改变字符颜色代码 MOV CX,79 MOV AH,09 LEA BX,SPA DISP5: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001010B ;黑底绿字 MOV CX,79 INT 10H POP CX POP BX INC BX LOOP DISP5 LEA DX,SPA CALL DISPLAY RET DIVIDE ENDP ;-----------数据转换为字符子程序----------- CHANGE PROC NEAR MOV DX,'$' ;将结束符入栈 PUSH DX MOV DX,'=' ;将等号入栈 PUSH DX MOV BX,0AH ;除数 MOV CX,3 MOV DX,0 MOV AX,NUM2 ;将第二个操作数送AX MARK1: CMP AX,0 JE OVER1 DIV BX ;除取余 ADD DX,30H ;加H转换为ASCⅡ码 PUSH DX ;将ASCⅡ码入栈 INC CX ;计数器加 MOV DX,0 JMP MARK1 OVER1: MOV DL,OP PUSH DX ;将运算符入栈 MOV DX,0 MOV AX,NUM1 ;将第一个操作数送AX MARK2: CMP AX,0 JE OVER2 DIV BX ;除取余 ADD DX,30H ;加H转换为ASCⅡ码 PUSH DX ;将ASCⅡ码入栈 INC CX ;计数器加 MOV DX,0 JMP MARK2 OVER2: LEA BX,STRING MARK3: POP DX ;将ASCⅡ码出栈 MOV [BX],DX ;将ASCⅡ码依次送STRING单元 INC BX LOOP MARK3 MOV BX,0AH ;除数 MOV CX,01 ;计数器初值为 MOV DX,24H PUSH DX ;将结束符入栈 MOV AX,ANSWER MARK12: MOV DX,0 CMP AX,0 JE OVER6 DIV BX ;除十取余 ADD DX,30H ;加H得到ASCⅡ码 PUSH DX ;将ASCⅡ码入栈 INC CX ;计数器加一 JMP MARK12 OVER6: CMP CX,01 JNE MARK13 MOV DX,30H PUSH DX ;若答案为零,将H入栈 INC CX MARK13: LEA BX,ANS MARK14: POP DX ;将ANSWER字符依次出栈 MOV [BX],DX ;将ANSWER字符依次存到ANS单元 INC BX LOOP MARK14 RET CHANGE ENDP ;--------------用户输入并判断对错子程序------------ INPUT PROC NEAR MOV CX,0 MARK4: MOV AH,01 ;01功能调用,输入字符 INT 21H CMP AL,0DH ;输入是否为回车 JE OVER3 ;是则表示输入结束 CMP AL,08 JE DELETE MOV AH,0 SUB AX,30H ;字符的ASCⅡ码减H PUSH AX ;将结果入栈 INC CX ;计数器加一 JMP MARK4 DELETE: MOV AH,02 MOV DL,08H INT 21H JMP MARK4 OVER3: MOV AX,ANSWER MARK5: MOV DX,0 MOV BX,0AH ;除数 DIV BX ;除 POP BX CMP DX,BX ;将输入结果与正确答案比较 JE MARK6 MOV BX,0FFH MOV FLAGE,BX ;与正确答案不同则将FLAGE置FFH MARK6: LOOP MARK5 CMP AX,0 JE MARK10 MOV BX,0FFH MOV FLAGE,BX MARK10: MOV AX,FLAGE CMP AX,0FFH ;查看FLAGE是否为FFH JE MARK7 ;以下为改变字符颜色代码 MOV CX,219 MOV AH,09 LEA BX,RIGHT DISP6: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001010B ;黑底绿字 MOV CX,219 INT 10H POP CX POP BX INC BX LOOP DISP6 LEA DX,RIGHT CALL DISPLAY ;不是则显示正确提示 MOV AX,PASS INC AX ;正确题数加一 MOV PASS,AX JMP OVER4 MARK7: MOV CX,240 ;以下为改变字符颜色代码 MOV AH,09 LEA BX,WRONG DISP7: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001100B ;黑底红字 MOV CX,240 INT 10H POP CX POP BX INC BX LOOP DISP7 LEA DX,WRONG CALL DISPLAY ;是则显示错误提示 MOV AH,02 MOV DL,0DH INT 21H MOV DL,0AH INT 21H ;换行 MOV AX,0 MOV FLAGE,AX ;将FLAGE清零 OVER4: MOV AX,TOTAL INC AX ;总题数加一 MOV TOTAL,AX RET INPUT ENDP ;-------------计算正确率子程序------------ ACCUR PROC NEAR MOV CX,2 MOV AX,PASS ;做对题数送AX MOV BX,64H MUL BX ;乘于 MOV BX,TOTAL ;所做总题数送BX DIV BX ;计算正确率 MOV DX,24H PUSH DX ;将结束符入栈 MOV DX,25H PUSH DX ;将百分号入栈 MOV DX,0 MOV BX,0AH ;除数 MARK8: CMP AX,0 JE OVER5 DIV BX ;除取余 ADD DX,30H ;加H得到ASCⅡ码 PUSH DX ;将ASCⅡ码入栈 INC CX ;计数器加一 MOV DX,0 JMP MARK8 OVER5: CMP CX,02 JNE MARK11 MOV DX,30H PUSH DX ;无做对题将零的ASCⅡ码入栈 INC CX MARK11: LEA BX,RATE MARK9: POP DX MOV [BX],DX ;将正确率的ASCⅡ码存RATE单元 INC BX LOOP MARK9 ;以下为改变字符颜色代码 MOV CX,52 MOV AH,09 LEA BX,RESULT DISP8: MOV AL,[BX] PUSH BX PUSH CX MOV BH,0 MOV BL,00001010B ;黑底绿字 MOV CX,52 INT 10H POP CX POP BX INC BX LOOP DISP8 LEA DX,RESULT CALL DISPLAY ;显示正确率 RET ACCUR ENDP ;----------------显示子程序--------------- DISPLAY PROC NEAR MOV AH,09 INT 21H RET DISPLAY ENDP CODE ENDS END START