汇编高手救命啊,要死人啦

60. (上机题)按同余法产生一组随机数 N(1<N<=50),并按 N+50 赋给 45 名同学的 5 门课
程的成绩,要求编程实现计算每个同学的平均成绩,并根据平均成绩统计全班的成绩各
等级的人数(A:90~100,B:80~89,C:70~79,D:66~69,E:60~65,F:60
分以下),按下列格式显示:
Total <总人数>
A: <人数 1>
B: <人数 2>
C: <人数 3>
D: <人数 4>
E: <人数 5>
F: <人数 6>
高手帮我一下啊,不过我只有20分,真的很急啊,发到邮箱[email protected]

; 题目名称:同余法产生一组随机数
; 题目来源:http://zhidao.baidu.com/question/129800729.html
; 本程序在MASMPlus 1.2集成环境下通过编译,经过调试,运行正确。
Code Segment
Assume CS:Code,DS:Code
; -------------------------------------
; 功能:显示指定地址(Str_Addr)的字符串
; 入口:
; Str_Addr=字符串地址(要求在数据段)
; 用法: Output Str_Addr
; 用法举例:Output PromptStr
Output MACRO Str_Addr
lea dx,Str_Addr
mov ah,9
int 21h
EndM
; -------------------------------------
; 功能:输出一个字符
; 入口:dl=要显示的字符
Output_Chr proc Near
push ax
mov ah,02h
int 21h
pop ax
ret
Output_Chr endp
; -------------------------------------
; 功能:显示、输出一个回车、换行
Output_CTLF proc Near
push ax
push dx
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
pop dx
pop ax
ret
Output_CTLF Endp
; -------------------------------------
; 功能:把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示
; 入口:AX=二进制数
; 出口:在当前光标位置显示转换后的ASCII码数字
Unsi_Dec_ASCII Proc Near
push dx
push bx
push di
mov bx,10
lea di,@@Temp_Save[5]
mov BYTE PTR [di],'$'
dec di
cld
@@Divide: xor dx,dx
div bx
or dl,30h
mov [di],dl
dec di
test ax,ax
jnz @@Divide
inc di
push di
pop dx
mov ah,9
int 21h
pop di
pop bx
pop dx
ret
@@Temp_Save db 6 dup(?)
Unsi_Dec_ASCII EndP
; -------------------------------------
; 功能:按同余法产生一组随机数 N(1<N<=50),公式:R=(R0*29+7) mod 50
; 入口参数:DH=50(模数)DL=随机数种子
; 出口参数:DL=新的随机数
Random Proc Near
mov al,27
mul dl
add ax,17
div dh
mov dl,ah ;余数(随机数)
ret
Random EndP
; -------------------------------------
Students equ 45 ;学生人数
Subjects equ 5 ;科目数
Grades db 6 dup(0) ; 各分数段计数
Prompt_Str db 'Total: $'
Press_Key db 7,13,10,13,10,'The complated. Press any key to exit...$'
Start: push cs
pop ds
push cs
pop es ;使数据段、附加段与代码段同段
; -------------------------------------
; 按同余法产生一组随机数 N(1<N<=50),并按 N+50 赋给45名同学的5门课程的成绩
@@Random: xor ax,ax
int 1ah ;取系统时钟嘀嗒数
cmp dl,49
ja @@Random ;大于49,无效数值,再取
mov dh,50 ;模数
mov cx,Students*Subjects ;45名学生5门课程成绩总数
lea di,Buffer ;成绩存放地址
cld
Scoring: mov al,dl ;随机数种子
add al,50 ;加50,生成学生成绩
stosb ;保存成绩
call Random ;按同余法产生一组随机数 N(1<N<=50)
loop Scoring
; -------------------------------------
; 计算每个同学的平均成绩
push di ;入栈保存平均成绩地址
lea si,Buffer ;成绩地址
mov cx,Students ;学生人数
Averaging: push cx
mov cx,Subjects ;课程数
xor bx,bx ;总成绩初值
xor ah,ah
Summing: lodsb
add bx,ax ;累加各科成绩
loop Summing
mov ax,bx
mov bl,Subjects
div bl
stosb ;保存一名学生的平均成绩
pop cx
loop Averaging
pop si ;弹出平均成绩地址
; -------------------------------------
; 根据平均成绩统计全班的成绩各等级的人数(A:90~100,B:80~89,C:70~79,D:66~69,E:60~65,F:60分以下)
mov dl,10 ; 用于除10
mov cx,Students ;学生人数
@@Statics: lodsb ; 提取成绩
xor ah,ah
div dl ; 除10
cmp al,5 ; >5,及格
jg $+4
mov al,5 ; <=5,不及格
sub al,5 ; 减5,分数段计数地址偏移量
xor ah,ah
push ax
pop bx
inc Grades[bx] ; 计数
loop @@Statics ; 循环,统计下一个成绩
mov al,Grades[5] ;取100分人数
add Grades[4],al ;加到90-100分数段
; -------------------------------------
; 按平均成绩显示各等级人数(A:90~100,B:80~89,C:70~79,D:60~69,E:60分以下)
Output Prompt_Str ;提示显示总人数
mov ax,Students ;学生人数
call Unsi_Dec_ASCII ;把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示
lea si,Grades[4] ;A级成绩地址
mov dh,'A' ;等级初值
mov cx,5 ;等级数
List_Grades: call Output_CTLF ;输出一个回车、换行
mov dl,dh
call Output_Chr ;显示一个字符
mov dl,':'
call Output_Chr ;显示一个字符
std
lodsb ;读取一个等级的人数
xor ah,ah
call Unsi_Dec_ASCII
inc dh
loop List_Grades
; -------------------------------------
Exit_Proc: Output Press_Key ;提示操作完成,按任意键结束程序
mov ah,1
int 21h
mov ah,4ch ;结束程序
int 21h
Buffer: ;45名学生5门课程的成绩
Code ENDS
END Start ;编译到此结束
温馨提示:答案为网友推荐,仅供参考
第1个回答  2009-12-18
死吧,我救不了你...
相似回答