📄 rank.asm
字号:
;数据段设置
DATA SEGMENT
GRADE DW 50 DUP( )
RANK DW 50 DUP( )
ENTER DB 'Grades:',24H ;提示用户输入成绩
ERROR DB 13,10,'Error!',13,10,24H ;用户输入的格式出错
SHOW DB 'Rank: ',24H
COUNT DW 0 ;统计输入的成绩个数
CR DB 13,10,24h ;换行
DATA ENDS
;*******************************************************************************
;堆栈段设置
STACK SEGMENT STACK
DB 400 DUP(0) ;初始化堆栈大小
STACK ENDS
;*********************************************************************************
;代码段设置
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
MOV ES,AX ;ES = AS
CALL INPUT ;调用INPUT
CALL RANKP ;调用RANKP
CALL OUTPUT ;调用OUTPUT
MOV AH,01H
INT 21H ;按任意键退出
MOV AX,4C00H
INT 21H ;退出程序
;******************************************************************************
;INPUT程序段
;以学号为序从键盘输入一个班的学生成绩,各个成绩之间 用逗号格开,最后以回车符结束。
;然后把一个班的成绩存入grade数组。
INPUT PROC NEAR
LEA DX,ENTER
MOV AH,9
INT 21H ;提示用户输入
MOV SI,0
MOV COUNT,0 ;将输入用户的输入个数置0
_ENTER: ;对用户的输入进行监视,对错误输入立即进行出错处理
CALL DECIBIN ;调用DECIBIN ;对用户输入进行处理
INC COUNT
CMP DL,',' ;与','比较,相同则保存成绩,不同出错
JE _STORE
CMP DL,0DH ;与回车键进行比较,回车则成绩输入结束
JE _ENDENTER
JNE _ERROR ;出错处理:显示出错信息
_STORE: ;保存成绩
MOV GRADE[SI],BX
ADD SI,2
JMP _ENTER
_ERROR:
LEA DX,ERROR
MOV AH,9
INT 21H
_ENDENTER: ;用户结束成绩输入
MOV GRADE[SI],BX
MOV DX,OFFSET CR ;换行
MOV AH,9
INT 21H
RET
INPUT ENDP
;*******************************************************************************************
;RANKP程序段
;从grade数组取得一个班的成绩,以学号为序计算出该班每个学生的名次存入rank数组。
;算法为:一个学生的名次等于成绩高于该生的学生人数加1
RANKP PROC NEAR
MOV DI,COUNT
MOV BX,0
_LOOP:
MOV AX,GRADE[BX] ;取学生成绩
MOV WORD PTR RANK[BX],0 ;初始化RANK[BX]的值为0
MOV CX,COUNT
LEA SI,GRADE ;第一个学生的成绩
_NEXT1:
CMP AX,[SI] ;比较两个成绩
JG _JUMP ;成绩大于被比较的跳过
INC WORD PTR RANK[BX]
_JUMP:
ADD SI,2 ;取下一个被比较成绩的地址
LOOP _NEXT1
ADD BX,2 ; 下一个成绩
DEC DI ;未比较成绩个数减1
JNE _LOOP
RET
RANKP ENDP
;******************************************************************************
;OUTPUT程序段
;从rank数组取得一个班的学生名次。把一个班的学生名次以学号为序在终端显示出来
;调用子模块binidec,以便把rank数组中的二进制数转成十进制数并在终端上显示出来.调用子模块crlf完成回车,换行功能.
OUTPUT PROC NEAR
LEA DX,SHOW
MOV AH,09H
INT 21H
MOV SI,0
MOV DI,COUNT
_NEXT2:
MOV BX,RANK[SI] ;将成绩保存到BX中
CALL BINIDEC ;调用BINIDEC
CMP DI,1 ;将剩余的成绩个数与1比较,若为1则不显示','
JE _NOCOMMA
MOV DL,','
MOV AH,02H
INT 21H ;显示','
_NOCOMMA:
ADD SI,02H ;取下一个成绩名次
DEC DI
JNZ _NEXT2
MOV DX,OFFSET CR ;换行
MOV AH,9
INT 21H
RET
OUTPUT ENDP
;******************************************************************************
;DECIBIN程序段
;从键盘取得一个十进制数。把该数转换成二进制数并存入BX寄存器中。
DECIBIN PROC NEAR
MOV BX,0
_CATCH:
MOV AH,01H
INT 21H
MOV DL,AL
SUB AL,30H
JL _ENDCHANGE ;小于则结束SFVOF=1
CMP AL,39H
JG _ENDCHANGE ;大于则结束
CBW
XCHG AX,BX ;AX与BX值交换
MOV CX,10
MUL CX ;无符号数乘法指令,(AX)<----(AL)*(CX)
XCHG AX,BX
ADD BX,AX ;(BX)<------(BX)+(AX)
JMP _CATCH
_ENDCHANGE:
RET
DECIBIN ENDP
;******************************************************************************
;BINIDEC程序段
;把bx寄存器中的二进制数转换成10进制数,并在终端屏幕上显示出来。调用dec_div来作除法运算并显示字符。
BINIDEC PROC NEAR
PUSH BX
PUSH CX
PUSH SI
PUSH DI ;压栈
MOV CX,10
CALL DEC_DIV ;调用DEC_DIV
MOV CX,1
CALL DEC_DIV ;调用DEC_DIV
POP DI
POP SI
POP CX
POP BX ;出栈
RET
BINIDEC ENDP
;******************************************************************************
;DEC_DIV程序段
;把bx中二进制数除以相应的十的幂,并在屏幕上显示一位商。余数保存在bx寄存器中。
DEC_DIV PROC NEAR
MOV AX,BX
MOV DX,0
DIV CX
MOV BX,DX
MOV DL,AL
ADD DL,30H
MOV AH,02H
INT 21H ;显示
RET
DEC_DIV ENDP
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -