PUSH SI PUSH DI PRINTTIP TIP2 ;打印提示信息,输入学号和分数 MOV TMP,0 ;记录是学号还是分数 XOR BX,BX ;记录每个ID的偏移量 XOR AX,AX ;记录学生数目 MORE: PRINTTIP CR ;打印回车换行 CMP COUNTB,AL ;比较,如果不等则跳转至HERE1 JNZ HERE1 JMP RETURN ;计数器为0则返回父程序 HERE1: CMP TMP,0 ;如果TMP中为0则打印学号,如果为1则打印分数 JE PR1 CMP TMP,1 JE PR2 PRINTTIP PRPRE1 ;打印学号 JMP HERE2 PRINTTIP PRPRE2 ;打印分数 PR1: PR2: HERE2: CALL GETIN ;否则接受输入 CALL CHECK ;检查输入是否是数字且不为空 CMP CHEOK,0 JNE CHEFAIL ;不为零则不合法,需要重新输入 CMP TMP,0 JE ISID ;输入的是学号 CMP TMP,1 JE ISMARK ;输入的是分数 CHEFAIL: PRINTTIP TIP0 ;重新输入提示信息 PRINTTIP CR MOV CHEOK,0 ;重新把返回判断位置零 JMP MORE ;写入学号,固定为16个字符
ISID: MOV DL,PRES ;抽取需要写入字符的个数 XOR DH,DH ;使DH为0 MOV CX,DX MOV SI,CX ;改变指针 INC CX MOV CHAR[SI],'$';把最后一个字符之后的位置填充为'$' ;开始写入ID MOV TMP,1 ;表示下一个是分数 CLD MOV SI,OFFSET CHAR ;字符的偏移地址 MOV DI,OFFSET ID ;学号的偏移地址 ADD DI,BX REP MOVSB ;写入ID,写完则为接受下一个输入BUFF作准备 ADD BX,16 ;ID的偏移地址向后挪动固定的16BYTE JMP MORE ;跳回继续输入下一个BUFF ;写入分数 ISMARK: CALL CHANGE ;将输入转为二进制数 CMP CHEOK,0 ;与0进行比较 JE WRITEMARK ;如果没有错误则开始写入分数 MOV ERROR1,4 ;如果不为0,说明格式有错误,打印错误提示信息 JMP CHEFAIL WRITEMARK: PUSH BX ;保护现场 MOV BL,MTMP MOV DI,AX MOV MARK[DI],BL;实际写入成绩 POP BX ;恢复现场 MOV TMP,0 ;计数清理,表明下一个输入为学号 INC AX ;已接受的学生个数加一 JMP MORE RETURN:
POP DI ;恢复现场 POP SI POP DX POP CX POP BX POP AX RET GETINFO ENDP ;-------------------------------------------------------- ;获得一次BUFF输入子程序 ;入口参数为BUFF的偏移地址,出口参数为BUFF中的字符串 GETIN PROC NEAR PUSH AX ;保存现场 PUSH DX PUSH DI MOV DX,OFFSET BUFF ;缓冲区字符的偏移地址 MOV AH,0AH INT 21H POP DI ;恢复现场 POP DX POP AX RET GETIN ENDP ;-------------------------------------------------------- ;执行输入字符是否是数字的合法性检查 CHECK PROC NEAR PUSH DI ;保护现场 PUSH CX PUSH AX XOR DI,DI ; 记录CHAR读取的偏移量 MOV AL,PRES ; 读取输入的BUFF中的字符数 CBW ;字节扩展 MOV CX,AX
CMP CX,0 ; 判断是否输入BUFF为空 JE ISEMPTY ; 为空则重新输入 AGAIN: CMP CX,DI JE RETURNCHECK ;如果为0则跳转 MOV AH,CHAR[DI] ;将数字的ASCII码传入AH CMP AH,30H ;和0进行比较 JL INVALID ; 小于则无效字符 CMP AH,39H JG INVALID ; 大于则是无效字符 INC DI JMP AGAIN ISEMPTY:MOV ERROR1,0 ;输入为空的处理代码 PRINTTIP CR ;打印换行回车 CALL PRINTERR ;打印错误提示信息 PRINTTIP CR MOV CHEOK,1 ;检错和1进行比较 JMP RETURNCHECK INVALID:MOV ERROR1,2 ;输入不合法的处理代码 PRINTTIP CR ;打印换行回车 CALL PRINTERR ;打印错误提示信息 PRINTTIP CR MOV CHEOK,1 ;将检测信息置1 RETURNCHECK: POP AX ;恢复现场 POP CX POP DI RET CHECK ENDP ;-------------------------------------------------------- ;处理成绩输入的子程序 ;检查输入成绩是否在0-100之间的子程序并转化为二进制数 CHANGE PROC NEAR ;把3位数字转换为二进制数 PUSH AX ;保护现场
PUSH BX PUSH CX MOV CL,PRES ;将实际的数字放入CL CMP CL,3 JA MINVALID ;四位数或以上,溢出 JE THRDIG ;三位数 CMP CL,2 JE TWODIG ;两位数 CMP CL,1 JE ONEDIG ;一位数 THRDIG: ;判断是否是100,是则直接在临时成绩区写入100 MOV BL,CHAR[0] ;百位 SUB BL,30H CMP BL,1 JNE MINVALID MOV BL,CHAR[1] ;十位 SUB BL,30H CMP BL,0 JNE MINVALID MOV BL,CHAR[2] ;个位 SUB BL,30H CMP BL,0 JNE MINVALID MOV MTMP,100 ;写入100 JMP CRETURN TWODIG: ; 当是两位数时判断十位是否是0,不是则进行转换,然后写入临时成绩中 MOV BL,CHAR[0] ;十位 SUB BL,30H CMP BL,0 JE MINVALID MOV AL,10 MUL BL ;成10取得十位数