MOV BL,CHAR[1] ;个位 SUB BL,30H ADD AL,BL ;因为小于100所以有效数在AL中,可以直接加个位数得到结果 MOV MTMP,AL ;写入转换后的数字 JMP CRETURN ONEDIG: ;一位数时直接写入临时成绩区即可 MOV BL,CHAR[0] ;个位 SUB BL,30H MOV MTMP,BL JMP CRETURN MINVALID: MOV ERROR1,4 ;给定错误信息类型 CALL PRINTERR ;调用打印信息错误提示 MOV CHEOK,1 ;将检错信息置1 CRETURN: POP CX ;恢复现场 POP BX POP AX RET CHANGE ENDP ;-------------------------------------------------------- ;打印错误信息子程序 PRINTERR PROC NEAR PUSH AX ;保护现场 PUSH DX PUSH BX MOV AL,ERROR1 ;错误信息 CBW ;字节扩展 MOV BX,AX MOV AH,09H MOV DX,ERRLIST[BX] ;将错误信息存入DX INT 21H POP BX ;恢复现场
POP DX POP AX RET PRINTERR ENDP ;-------------------------------------------------------- ;冒泡排序子程序 SORT PROC NEAR PUSH AX ;保护现场 PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI ;写入偏移量作为分数的指针 MOV AL,COUNTB ;读取学生数目 XOR BX,BX ;BX作为寻址计数器 ;顺序写入成绩偏移量 SLOP: DEC AL MOV RANKTMP[BX],AL ;依次排除学生的名次 INC BX CMP AL,0 ;如果排名没有结束则继续循环 JNE SLOP ;排序名次,冒泡排序法 MOV CX,COUNTW ;CX记录了总的学生人数 DEC CX JZ WRRAK ;如果只有一个学生则直接写入名次,否则排序异常 LOP1: XOR DI,DI ;从第一个名次开始 LOP2: MOV AL,RANKTMP[DI];取出地址指针,即成绩偏移量 XOR AH,AH MOV SI,AX MOV DL,MARK[SI] ;取出成绩1 MOV AL,RANKTMP[DI+1]
XOR AH,AH MOV SI,AX MOV DH,MARK[SI] ;同理取出成绩2 CMP DL,DH JGE NEXTCMP MOV AH,RANKTMP[DI] ;交换分数指针 XCHG AH,RANKTMP[DI+1] MOV RANKTMP[DI],AH NEXTCMP: INC DI ;个数增加1 CMP DI,CX ;如果如输入学生个数不等则继续循环LOP2 JNE LOP2 LOOP LOP1 ;循环LOP1 ;写入最后的名次 WRRAK: XOR SI,SI MOV CX,COUNTW MOV BL,1 ;保存名次 LOPSAVE: CMP SI,CX JE FINISH MOV AL,RANKTMP[SI] ;提取该名次学生的地址指针 XOR AH,AH MOV DI,AX MOV RANK[DI],BL ;写入该学生的名次 INC BL INC SI JMP LOPSAVE ;继续循环 FINISH: POP DI ;恢复现场 POP SI POP DX POP CX POP BX POP AX RET
SORT ENDP ;-------------------------------------------------------- ;打印输入成绩和名次子程序 PRINT PROC NEAR PUSH AX ;保护现场 PUSH BX PUSH CX PUSH DX PUSH SI PRINTTIP CR PRINTTIP PRTIP ;打印提示信息 PRINTTIP CR PRINTTIP PRINFO PRINTTIP CR MOV CX,COUNTW ;CX用于保存学生人数 XOR SI,SI ;SI用于指明当前处理的学生的序号 XOR BX,BX ;BX保存当前输入的学号偏移量,每次增16 NEXPRINT: MOV TMP[1],0 ;对打印名次置标志位,表明没有打印名次 CMP SI,CX JNE PRINTID JMP PRET PRINTID: ;打印学号,直接字符串打印,因结尾写入了'$' MOV AH,09H MOV DX,OFFSET ID ADD DX,BX INT 21H PRINTTIP TAB PRINTMARK: ;打印分数,分为100、10-99、0-9三中情况打印 MOV AL,MARK[SI] PRINTRANK: ;打印排名 CMP AL,100 JE PTTHR
CMP AL,10 JL PTONE JMP PTTWO PTTHR: ;是100则直接输出字符串即可,不必转化 PRINTCHAR '1' ;字符串100 PRINTCHAR '0' PRINTCHAR '0' JMP NEXT PTTWO: ;10-99需要除以10,商和余数分别是十位和个位 CBW ;字节扩展 PUSH BX MOV BL,10 DIV BL ;数字除以10,得到商(十位) MOV BX,AX ADD BL,30H ;将数字转变为ACII码 ADD BH,30H PRINTCHAR BL ;打印个位 PRINTCHAR BH ;打印十位 POP BX JMP NEXT PTONE: ;0-9直接二进制转到ASCII码然后输出 ADD AL,30H PRINTCHAR AL NEXT: PRINTTIP TAB ;开始打印名次,和打印成绩复用代码 MOV AL,RANK[SI] ;将排名信息给AL CMP TMP[1],0 ;如果不为0则继续打印学生信息 JNE FINISHP MOV TMP[1],1 JMP PRINTRANK ;跳转至打印排名 FINISHP: PRINTTIP CR ;打印完一个学生的学号成绩及名次,回车换行