匯編語言成績匯總
題目要求:
對輸入的一些成績進行分類匯總。
要求:
-
所有數字由鍵盤輸入;
-
輸入的成績個數為任意個(至少 10 個);
-
對成績進行歸類並輸出顯示在屏幕:
-
顯示最高成績、最低成績、平均成績(平均成績保留一位小數)
-
顯示 90-100 分人數,80-89 分人數,70-79 分人數,60-69 分人數,低於 60 分人數,
-
顯示無效數字個數(非數字或大於 100 數字個數)
代碼:
;-----數據段------
DATAS SEGMENT
STR1 DB 'PLEASE INPUT SCORES',0AH,0DH,'$'
STR2 DB 0AH,0DH,'THE HIGHEST SCORE IS:','$'
STR3 DB 0AH,0DH,'THE LOWEST SCORE IS:','$'
STR4 DB 0AH,0DH,'AVERAGE SCORE IS:','$'
STR5 DB 0AH,0DH,'THE NUMBER OF ERROR SCORE:','$'
STR6 DB 0AH,0DH,'THE NUMBER OF CORRET SCORE:','$'
STR7 DB 0AH,0DH,'THE NUMBER OF 90--100;','$'
STR8 DB 0AH,0DH,'THE NUMBER OF 80--90:','$'
STR9 DB 0AH,0DH,'THE NUMBER OF 70--80:','$'
STR10 DB 0AH,0DH,'THE NUMBER OF 60-70:','$'
STR11 DB 0AH,0DH,'THE NUMBER OF <60:','$'
STR12 DB 0AH,0DH,'THE SUM OF SCORES:','$'
SCORES DW 256 DUP(0);輸入的成績數組
STAS DW 20 DUP(0);各個統計量
DATAS ENDS
;-----堆棧段-------
STACKS SEGMENT
DW 256 DUP(0)
STACKS ENDS
;-----代碼段-------
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
MOV DX,OFFSET STR1;輸出提示1
MOV AH,09H
INT 21H
;---輸入數據---
MOV CX,0FFH;將計數器CX設為一個大數,在循環內部進行循環的跳出
MOV SI,0
INPUTS:
CALL INPUT
ADD SI,2;偏移地址指向下一個
LOOP INPUTS
;---計算各統計量---
STATS:
MOV SI,0
CALL STAT
;---打印最大值---
PRINT_MAX:
MOV DX,OFFSET STR2;輸出提示2
MOV AH,09H
INT 21H
MOV SI,0
CALL PRINT
;---打印最小值---
PRINT_MIN:
MOV DX,OFFSET STR3;輸出提示3
MOV AH,09H
INT 21H
MOV SI,2
CALL PRINT
;---打印錯誤輸入個數---
PRINT_ERR:
MOV DX,OFFSET STR5;輸出提示5
MOV AH,09H
INT 21H
MOV SI,16
CALL PRINT
;---打印數組長度,即正確輸入個數---
PRINT_LEN:
MOV DX,OFFSET STR6;輸出提示6
MOV AH,09H
INT 21H
MOV SI,18
CALL PRINT
;---打印90-100成績個數---
PRINT_S9:
MOV DX,OFFSET STR7;輸出提示7
MOV AH,09H
INT 21H
MOV SI,6
CALL PRINT
;---打印80-89成績個數---
PRINT_S8:
MOV DX,OFFSET STR8;輸出提示8
MOV AH,09H
INT 21H
MOV SI,8
CALL PRINT
;---打印70-79成績個數---
PRINT_S7:
MOV DX,OFFSET STR9;輸出提示9
MOV AH,09H
INT 21H
MOV SI,10
CALL PRINT
;---打印60-69成績個數---
PRINT_S6:
MOV DX,OFFSET STR10;輸出提示10
MOV AH,09H
INT 21H
MOV SI,12
CALL PRINT
;---打印<60的成績個數---
PRINT_S5:
MOV DX,OFFSET STR11;輸出提示11
MOV AH,09H
INT 21H
MOV SI,14
CALL PRINT
;---打印成績和---
PRINT_SUM:
MOV DX,OFFSET STR12;輸出提示12
MOV AH,09H
INT 21H
MOV SI,4
CALL PRINT
;---打印平均數,且保留一位小數---
PRINT_AVG:
PRINT_1:
MOV DX,OFFSET STR4;輸出提示4
MOV AH,09H
INT 21H
CALL AVERAGE
MOV SI,4
CALL PRINT;打印整數位
;---平均數小數計算----
AVG_FLOAT:
;---計算第一位小數---
MOV AX,DX
MOV CX,10
MUL CX
MOV CX,STAS[18];數組長度
MOV DX,0
DIV CX
MOV STAS[4],AX;第一位小數存入STAS[4]
;---繼續四舍五入得第二位小數---
MOV AX,DX
MOV CX,10
MUL CX
MOV CX,STAS[18];數組長度
MOV DX,0
DIV CX
CMP AX,5;第二位小數和5比較
JB PRINT_2
INC STAS[4];第二位小數大於5,則第一位小數加一
PRINT_2:
MOV DL,'.';打印小數點
MOV AH,02H
INT 21H
PRINT_3:
MOV SI,4;打印小數位
CALL PRINT
EXIT:
MOV AH,4CH
INT 21H
;-----------主程序段結束------------
;-----------子程序段------------
;-----------輸入子程序-------------
INPUT PROC NEAR
PUSH AX;保護除CX外的寄存器,因為CX是循環計數器所以不能入棧
PUSH BX
PUSH DX
MOV BX,0
CLC
INLP:
MOV AH,01H
INT 21H
CMP AL,20H;和空格比較,是就跳到SAVE
JE SAVE
CMP AL,0DH;和回車比較,是就跳到OVER
JE OVER
;---錯誤字符處理,0<AL<9---
CMP AL,30H
JL ERR
SUB AL,30H
CMP AL,9
JG ERR;出現錯誤后進行處理
;---正常字符操作---
MOV AH,0;AH置零,便於數據儲存
XCHG AX,BX;BX中存有輸入成績的上一位,將其存於AX,並將輸入成績的當前為存於BX
MOV DX,10
MUL DX;將AX中數據,即成績的上一位乘以10
ADD BX,AX;將兩位加起來並存入BX,等待下次操作
JMP INLP
SAVE:
CMP BX,64H;和100比較
JA SAVE_ERR;大於100則跳到錯誤保存
MOV SCORES[SI],BX;輸入成績存入數組
INC STAS[18];數組長度+1
POP DX
POP BX
POP AX
RET
SAVE_ERR:
MOV AX,STAS[16];錯誤數據數+1
INC AX
MOV STAS[16],AX
SUB SI,2
POP DX
POP BX
POP AX
RET
OVER:
MOV CX,1;計數器記為1,本次輸入數據保存后退出循環
JMP SAVE;保存最后輸入的數據
OVER_ERR:
MOV CX,1
JMP SAVE_ERR
ERR:
MOV AH,01H;等待下個輸入
INT 21
CMP AL,20H;空格就跳到錯誤保存
JE SAVE_ERR
CMP AL,0DH;回車就調到錯誤結束
JE OVER_ERR
JMP ERR;否則即繼續等待下個輸入
RET
INPUT ENDP
;---------統計子程序----------
STAT PROC NEAR
PUSH DX
PUSH CX
PUSH BX
PUSH AX
MOV CX,STAS[18];數組長度
ADD CX,CX
MOV AX,SCORES[SI]
MOV BX,0;最小成績0
MOV DX,64H;最大成績,16進制的100
COMP:
MOV AX,SCORES[SI]
CMP AX,5AH;和90比較
JG S90
CMP AX,50H;和80比較
JG S80
CMP AX,45H;和70比較
JG S70
CMP AX,3CH;和60比較
JG S60
JMP S59
S90:
INC STAS[6];90-100
JMP SUM
S80:
INC STAS[8];80-90
JMP SUM
S70:
INC STAS[10];70-80
JMP SUM
S60:
INC STAS[12];60-70
JMP SUM
S59:
INC STAS[14];<60
JMP SUM
SUM:
ADD STAS[4],AX;求和,存入STAS[4]
;-----找最大值,暫存於BX----
MAX:
CMP BX,SCORES[SI];小於BX,就跳過,大於BX,就更新BX
JNB MIN
MOV BX,SCORES[SI]
;-----找最大值,暫存於DX----
MIN:
CMP DX,SCORES[SI];大於DX,就跳過,小於BX,就更新BX
JNA NEWDATA
MOV DX,SCORES[SI]
NEWDATA:
ADD SI,2
CMP SI,CX;判斷是否循環完了整個數組
JB COMP
MOV STAS[0],BX;最大值存入STA[0]
MOV STAS[2],DX;最小值存入STA[2]
POP AX
POP BX
POP CX
POP DX
RET
STAT ENDP
;-------打印子程序-----
PRINT PROC NEAR
PUSH DX
PUSH CX
PUSH BX
PUSH AX
;------每次打印一位字符------
MOV CX,0;記錄入棧次數
MOV AX,STAS[SI];每次要打印的內容存入AX中
MOV BX,10
PUS:
;-----低位先入棧,高位后入棧
MOV DX,0
DIV BX ;除以10
PUSH DX;將余數入棧
INC CX;記錄入棧次數作為輸出時的循環次數
CMP AX,0
JNZ PUS;當商為0時退出循環
POS:
;-----高位先輸出,低位后輸出
POP DX
ADD DX,30H
MOV AH,2
INT 21H
LOOP POS
POP AX
POP BX
POP CX
POP DX
RET
PRINT ENDP
;-------平均數子程序------
AVERAGE PROC NEAR
PUSH AX
PUSH BX
MOV DX,0
MOV AX,STAS[4];將SUM給AX
MOV BX,STAS[18];將數組長度給BX
DIV BX
MOV STAS[4],AX;將商存在原SUM的位置
POP BX
POP AX
RET
AVERAGE ENDP
CODES ENDS
END START