📄 huibian2.asm
字号:
;*************************************************************************
; 本程序可以对99个同学的4次成绩进行加权求其总评成绩
; 要求输入的学生姓名不超过5个字符(超过部分将被截取)
; 4次成绩只能输入两位整数,输出为三位,其中一位为小数
; 暂无排序功能,期待huibian3的改进,将加入排序、可输入小数等实现
;****************************************************************************
data segment
number_tip db 'Please input the number of students:','$'
name_tip db 0dh,0ah,'Please input the student name:$'
gradetip db 0dh,0ah,'Please input the grades:$'
show_result db 0dh,0ah,'Name : ChengJi',0dh,0ah,0dh,0ah,'$'
stars db 0dh,0ah,'************************************','$'
maohao db ' : $'
snumber1 db 100 dup(0) ;存储学生总数(ASCII表示)
snumber2 db 0 ;存储学生总数(十进制)
student db 792 dup(0) ;姓名,最多支持99个人
buffer1 db 8 dup(0) ;为学生成绩分配空间(ASCII表示)
buffer2 db 4 dup(0) ;为学生成绩分配空间(十进制表示)
resultes db 99 dup(3 dup(0)) ;存储每个学生平均分,每个人的平均分占用3单元,共99人
data ends
;**************************************************************************
code segment
;-----------------------------------------------------------
main proc far
assume cs:code,ds:data
start:
mov ax,data ;数据段初始化
mov ds,ax
mov si,0 ;指向每个学生姓名
mov di,0 ;指向每个学生总评成绩
mov cx,100 ;初始化学生数
;---------------------------------------------------------------------------
lea dx,number_tip ;请求输入学生总数
mov ah,09
int 21h
call store_number ;存储学生总数,结果送cx中
mov bx,cx ;bx暂存学生总数,以便调用display子程序时循环输出使用
cmp cx,0 ;输入学生数为0,退出
jle retdos
cmp cx,100 ;学生数超出本程序范围,退出
jge retdos
;--------------------------------------------------------------------------------
begin:
lea dx,name_tip ;请求输入学生姓名,不得大于5个字符,多出部分被截掉,可更改长度
mov ah,09
int 21h
call store_name ;存储学生姓名
add si,9 ;指向下一个学生姓名
lea dx,gradetip ;请求输入学生成绩
mov ah,09
int 21h
call store_grades ;存储每个学生成绩
call compute ;计算每个学生平均分
add di,3 ;分别存储每个学生的平均分,di指向每个学生平均分
;因为存储的是3位,di每次加3才能指向下一个学生
loop begin ;循环,直到输入所有学生成绩
call display ;显示结果
;----------------------------------------------------------------------
retdos:
mov ah,1 ;任意键结束
int 21h
mov ax,4c00h ;返回DOS
int 21h
;**************************************************************************
; 以下为子程序部分
;**************************************************************************
; 以下为子程序部分
;*************************************************************************
store_number proc
push ax
push bx
mov bx,0
store:
mov ah,01
int 21h ;输入字符
cmp al,0dh ;判断是否输入回车
je cr_ ;输入结束
and al,0fh ;转换成非压缩的BCD码
mov snumber1[bx],al
inc bx ;输入未结束,则继续输入
jmp store
cr_:
cmp bx,2 ;学生数大于10,还是小于10,最多支持99人
jz llll
jg large ;学生数大于99返回,bx>2
mov al,snumber1
jmp lllll
llll: mov ah,snumber1 ;BCD码转换为二进制数
mov al,snumber1+1
aad
lllll: mov snumber2,al
mov cx,0
mov cl,snumber2
large:
pop bx
pop ax
ret
store_number endp
;****************************************************************************
store_name proc
push dx
push ax
push bx
mov al,8 ;每个学生单元能存储的最大字符个数
mov student[si],al
lea dx,student[si] ;读取学生姓名
mov ah,0ah
int 21h
mov bl,student[si+1] ;bl存储实际输入字符个数
cmp bl,5 ;限制学生姓名字符数
jg limit
jmp continue
limit:
mov bl,5
continue:
mov bh,0
mov student[si+bx+2],'$' ;在最后加上'$'
pop bx
pop ax
pop dx
ret
store_name endp
;*****************************************************************************
store_grades proc
push ax
push di
mov di,0
input:
mov ah,1
int 21h ;输入字符
cmp al,0dh ;判断是否输入回车
je return ;输入结束
cmp al,' ' ;判断是否输入空格
;************重大失误!!!我竟然写成cmp al,0ah!!!结果使计算结果老是出错!浪费一个下午!
je input ;跳过空格
and al,0fh ;转换成非压缩的BCD码
mov buffer1[di],al
inc di ;输入未结束,则继续输入
jmp input
return:
pop di
pop ax
ret
store_grades endp
;****************************************************************************
compute proc ;计算平均成绩主程序
push ax
push si
push cx
push dx
push bx ;bx用做临时存储数据用
mov si,0
mov ax,0
mov dx,0
mov bx,0
;-----------------------------------------------------------------
mov cx,4 ;循环实现BCD码转换为二进制数
next1:
mov ah,buffer1[si]
mov al,buffer1[si+1]
aad
mov buffer2[bx],al
add si,2
inc bx
loop next1
;------------------------------------------
;期末成绩×0.6+期中成绩×0.2+实验成绩*0.1+平时成绩*0.1
mov si,0 ;计算平均成绩,结果用十进制表示
mov bx,0 ;清零
mov al,6
mul buffer2[si]
add bx,ax
mov al,2
mul buffer2[si+1]
add bx,ax
mov al,1
mul buffer2[si+2]
add bx,ax
mov al,1
mul buffer2[si+3]
add bx,ax
mov ax,bx
mov cl,10
div cl
;-----------------------------------------------------------------
;将结果转化为ASCII码存储
or ah,30h ;小数部分
mov resultes[di+2],ah
aam
or al,30h ;转换为ASCII码
or ah,30h
mov resultes[di],ah ;十位
mov resultes[di+1],al ;个位
;==============================================================================
pop bx
pop dx
pop cx
pop si
pop ax
ret
compute endp
;*****************************************************************************
display proc
push ax
push dx
lea dx,stars ;显示一行星号
mov ah,9
int 21h
;---------------------------------------------------------------------------
lea dx,show_result ;显示输出结果提示字符
mov ah,9
int 21h
;--------------------------------------------------------------------
mov si,0
mov di,0
mov cx,bx ;bx中存的是学生总数
output: ;循环输出,直至输出所有学生姓名及成绩
;--------------------------------------------------------------------------
lea dx,student[si] ;显示学生姓名
add dx,2 ;姓名的首地址
mov ah,9
int 21h
lea dx,maohao ;显示一个冒号
mov ah,9
int 21h
;-------------------------
mov dl,resultes[di] ;显示学生平均成绩(十位)
mov ah,2
int 21h
mov dl,resultes[di+1] ;显示学生平均成绩(个位)
mov ah,2
int 21h
mov dl,'.' ;打印小数点
mov ah,2
int 21h
mov dl,resultes[di+2] ;显示学生平均成绩(小数位)
mov ah,2
int 21h
;-------------------------------------------------------------------
mov ah,02h ;每打印出一个学生姓名及成绩就回车换行一次
mov dl,0dh
int 21h
mov dl,0ah
int 21h
;----------------------------------
add si,9
add di,3
loop output
;-----------------------------------------------------------------------
lea dx,stars ;显示一行星号
mov ah,9
int 21h
pop dx
pop ax
ret
display endp
;****************************************************************************
main endp
;-------------------------------------------------------------------------
code ends
;*************************************************************************
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -