实现功能:
- 键盘输入学生信息,包括学号,姓名,成绩
- 通过学号\姓名查询成绩
- 成绩排序
- 显示每个分段的人数(90-100、80-89、60-79、0-59)
- 最高分、最低分、平均分
- 退出系统
assume cs:code,ds:data,es:data,ss:stack
data segment
showmenu db 'Please enter a number(1-6) to chose FUNCTION ',0DH,0AH,
'-----------------------------------------------------',0DH,0AH,
'| FUNCTION1:input id(0000) name comgrade fingrade |',0DH,0AH,
'| FUNCTION2:enter 1(id)/2(name) to query grade |',0DH,0AH,
'| FUNCTION3:sort grade |',0DH,0AH,'$'
showmenu0 db '| FUNCTION4:show each level |',0DH,0AH,
'| FUNCTION5:show avg,max,min grade |',0DH,0AH,
'| FUNCTION6:quit |',0DH,0AH,
'-----------------------------------------------------',0DH,0AH,'$'
shows db 'please enter your choice:','$'
show0 db 'Welcome to use the system again,goodbye!','$'
FUN dw function1,function2,function3,function4,function5,function6
show10 db 'please enter the number of students:','$'
show11 db 'id name comgrade fingrade',0dh,0ah,'$';录入学生信息的提示,0dh enter 0ah 换行
show2 db ' ','$'
show3 db 'id name comgra fingra tolal rank',0dh,0ah,'$'
show40 db 'select id(1) or name(2) to query:','$'
show41 db 'please enter id:','$'
show42 db 'please enter name:','$'
show43 db 'cannot find such id/name',0dh,0ah,'$'
show44 db 'total grade:','$'
show51 db ' 0-59:','$'
show52 db '60-79:','$'
show53 db '80-89:','$'
show54 db '90-100:','$'
show61 db 'avrage grade:','$'
show62 db 'highest grade:','$'
show63 db 'lowest grade:','$'
count dw 0;存放录入学生人数
count1 dw 4,12,4,2;对应要输入信息循环次数
count2 dw 10;用于将得到的数字字符转成十进制时,/10操作 一个常数
count3 dw 0;用来记录输入名字时偏移地址信息
count4 dw 0;记录第i人录入名字
count5 dw 0,0,0,0,0,0,100,'$';前4个保存各分段人数 后3个保存平均分,最高分,最低分
SNO dw 100 dup(?)
SNAME db 200 dup(' ')
COMGRADE dw 100 dup(?)
FINGRADE dw 100 dup(?)
TOLGRADE1 dw 100 dup(?)
TOLGRADE dw 100 dup(?)
RANK dw 100 dup(?)
grade_addr dw 20 dup(0);grade相对地址
name_addr dw 20 dup(0);name相对地址
divition dw 1000,100,10,1
results db 0,0,0,0,'$'
cal_parm db 40,3,5
selection dw 0;查询选择
str1 db 10;最大长度
db 0;接收字符串的实际长度
db 10 dup(0);字符串
str_num db 20 dup(0);放name长度 用于查询名字时,长度比较
data ends
stack segment
dw 100 dup(?)
stack ends
code segment
out_str MACRO Y;输出字符串 宏定义
lea dx,Y;将Y地址赋给dx
mov ah,9h;使用int21 9号功能 ds:dx为字符串首地址,$为结束符
int 21h
ENDM
NUMBER MACRO;输入学生数
out_str show10
call input
lea si,count
mov word ptr [si],bx;人数存在count
ENDM
change_line MACRO;换行
push dx
push ax
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
pop ax
pop dx
ENDM
start:
mov ax,data
mov ds,ax
mov es,ax
NUMBER
call menu
start0:
change_line
out_str shows
mov ah,01h
int 21h;输入选择
sub al,30h
cmp al,0
jb start0
cmp al,6
ja start0
dec al
shl al,1
xor ah,ah
mov bx,ax
change_line
call FUN[bx];调用功能
jmp start0
mov ax,4c00h
int 21h
menu PROC
change_line
out_str showmenu
out_str showmenu0
ret
menu ENDP
function1 PROC near;功能1 输入学生的信息
out_str show11
lea si,count;lea 将count偏移地址送入si中
mov cx ,word ptr [si]
mov si,0
one:
call input;将id存入
mov word ptr SNO[si],bx;
out_str show2
call input1;存名字
out_str show2
call input;存16次作业成绩
mov word ptr COMGRADE[si],bx
out_str show2
call input;存大作业成绩
mov word ptr FINGRADE[si],bx
out_str show2
mov RANK[si],cx
add si,2
change_line
loop one
call cal_function;录入信息后立即计算成绩
ret
function1 ENDP
cal_function PROC
push si
push bx
mov si,0
mov bx,0
mov cx,count[0]
cal_one:
mov ax,COMGRADE[si]
div cal_parm[0]
mov ah,0
add TOLGRADE[bx],ax
add TOLGRADE1[bx],ax;副本
mov ax,FINGRADE[si]
mul cal_parm[1]
div cal_parm[2]
mov ah,0
add TOLGRADE[bx],ax
add TOLGRADE1[bx],ax
add si,2
add bx,2
loop cal_one
pop si
pop bx
ret
cal_function ENDP
function2 PROC
mov cx,count[0]
mov si,0
mov di,0
out_str show40
call input;输入查询选择 1 id 2 name
cmp bx,1
je ID_SEQ
cmp bx,2
je NAME_QUE
cmp bx,1
jb QUE_QUIT1
cmp bx,2
jb QUE_QUIT
cmp bx,2
ja QUE_QUIT1
ID_SEQ:
mov selection[0],1
out_str show41
call input;输入学号
id_cmp:
cmp SNO[si],bx
je QUE_QUIT;相等输出所有信息
add si,2
loop id_cmp
out_str show43;未找到匹配的id或名字,输出提醒
jmp QUE_QUIT1
NAME_QUE:
mov selection[0],2
out_str show42
mov bx,0
mov bp,0
push count[0]
lea dx,str1
mov ah,10;输入字符串到str1
int 21h
change_line
xor ah,ah;清0
mov al,str1[1];输入字符串实际长度
STR_CMP:
cmp al,str_num[bp];如果输入字符串与名字长度不同,则直接跳过 同时最终成绩与名字长度都定义db,可以用bp表示第i个
jne len_dif
lea si,SNAME[bx]
lea di,str1[2]
mov cx,ax
cld
repe cmpsb
je QUE_NAME_QUIT;相等跳到QUE_NAME_QUIT
len_dif:
add bl,str_num[bp]
inc bl;跳过'$'
inc bp
dec count[0]
cmp count[0],0
ja STR_CMP
out_str show43;未找到匹配的id或名字,输出提醒
jmp QUE_QUIT1
QUE_NAME_QUIT:
pop count[0]
jmp QUE_QUIT
QUE_QUIT:
out_str show44
.if selection[0]==1
mov ax,TOLGRADE[si]
.endif
.if selection[0]==2
add bp,bp
mov ax,TOLGRADE[bp]
.endif
call output;输出成绩
change_line
QUE_QUIT1:
ret
function2 ENDP
function3 PROC
mov si,0;设置参数
mov cx,count[0]
dec cx
mov ax,0
loopOne:
push cx
push si
loopTwo:
mov ax,TOLGRADE1[si]
cmp ax,TOLGRADE1[si+2]
jna next
xchg ax,TOLGRADE1[si+2]
xchg ax,TOLGRADE1[si]
mov ax,grade_addr[si];交换地址
xchg ax,grade_addr[si+2]
xchg ax,grade_addr[si]
next:
add si,2
loop loopTwo
pop si;
pop cx;
loop loopOne
mov cx,count[0]
mov si,0
out_str show3
sort_print:
mov di,grade_addr[si]
add di,di
mov ax,SNO[di];id
call output
out_str show2
lea dx,SNAME
add dx,name_addr[di]
mov ah,09h
int 21h;name
out_str show2
mov ax,COMGRADE[di];comgrade
call output
out_str show2
mov ax,FINGRADE[di];fingrade
call output
out_str show2
mov ax,TOLGRADE[di];total
call output
out_str show2
mov ax,RANK[si];rank
call output
change_line
add si,2
loop sort_print
ret
function3 ENDP
function4 PROC;各分段
mov cx,count[0]
mov ax,0
lea di,TOLGRADE
push cx
push di
total_grade:
mov bx,[di]
.if bx>count5[10]
mov count5[10],bx;最大值
.endif
.if bx<count5[12]
mov count5[12],bx;最小值
.endif
add ax,bx;成绩总和放在ax里
add di,2
loop total_grade
xor dx,dx
div count[0]
mov count5[8],ax;存入平均分
pop di
pop cx
four_grade:
cmp word ptr [di],60
jb L1
cmp word ptr [di],80
jb L2
cmp word ptr [di],90
jb L3
inc count5[6];90-100分段人数
jmp sta_exit
L1:
inc count5[0];0-59
jmp sta_exit
L2:
inc count5[2];60-79
jmp sta_exit
L3:
inc count5[4];80-89
jmp sta_exit
sta_exit:
add di,2
loop four_grade
out_str show51
mov ax,count5[0]
call output
change_line
out_str show52
mov ax,count5[2]
call output
change_line
out_str show53
mov ax,count5[4]
call output
change_line
out_str show54
mov ax,count5[6]
call output
change_line
ret
function4 ENDP
function5 PROC
out_str show61
mov ax,count5[8]
call output
change_line
out_str show62
mov ax,count5[10]
call output
change_line
out_str show63
mov ax,count5[12]
call output
change_line
ret
function5 ENDP
function6 PROC
out_str show0
mov ah,4ch
int 21h
ret
function6 ENDP
input PROC ;输入数字 bx返回十进制
mov bx,0
num:
mov ah,1;输入一位字符到al
int 21h;int 21 1号功能 键盘输入并回显 输入字符存在al上
sub al,30h;数字字符ascii转换为10进制数字
jb exit
cmp al,9
ja exit;不是数字直接退出
cbw
xchg ax,bx
mul count2[0]
xchg ax,bx
add bx,ax
jmp num;输入为数字时,继续循环 空格或enter退出循环
exit:
ret
input ENDP
input1 PROC near;输入名字 名字用s
mov bx,count3[0] ;保存下次存放name的偏移地址
mov di,count4[0];记录第i人
mov bp,di
add bp,bp
mov name_addr[bp],bx;记录每个名字的起始地址
mov grade_addr[bp],di;成绩相对地址
char1:
mov ah,1;
int 21h;
; cmp ah,08h;如果是backspace
; je backspace1
cmp al,61h
jb exit1
cmp al,7ah
ja exit1;不是小写字母跳转
mov SNAME[bx],al
inc bx
jmp char1;输入为小写字母继续循环,空格或enter退出循环
exit1:
mov SNAME[bx],'$';结束符,用于sort输出
inc count4[0]
sub bx,count3[0]
mov str_num[di],bl;名字长度
inc bx
add count3[0],bx
ret
input1 ENDP
output PROC;输出数字
push si
push di
push cx
mov si,offset divition
mov di,offset results
mov cx,4
cal:
mov dx,0
div word ptr [si];ax/1000
add al,30h
mov byte ptr [di],al;将结果从高位到低位存入results
inc di
add si,2
mov ax,dx;余数给回
loop cal
mov cx,3;检测数据前3位是否是0,不是则显示
mov di,offset results
nz:
cmp byte ptr [di],'0'
jne print
inc di
loop nz
print:
mov dx,di
mov ah,9h
int 21h
pop cx
pop di
pop si
ret
output ENDP
code ends
end start
菜单显示模块
assume cs:code,ds:data
data segment
showmenu db 'Please enter a number(1-6) to chose FUNCTION ',0DH,0AH,
'-----------------------------------------------------',0DH,0AH,
'| FUNCTION1:input id(0000) name comgrade fingrade |',0DH,0AH,
'| FUNCTION2:enter 1(id)/2(name) to query grade |',0DH,0AH,
'| FUNCTION3:sort grade |',0DH,0AH,'$'
showmenu0 db '| FUNCTION4:show each level |',0DH,0AH,
'| FUNCTION5:show avg,max,min |',0DH,0AH,
'| FUNCTION6:quit |',0DH,0AH,
'-----------------------------------------------------',0DH,0AH,'$'
shows db 'please enter your choice:','$'
show0 db 'Welcome to use this system again!','$'
show10 db 'please enter the number of students:','$'
count dw 0
count2 dw 10
FUN dw function1,function2,function3,function4,function5,function6
data ends
code segment
out_str MACRO Y;输出字符串 宏定义
lea dx,Y;将Y地址赋给dx
mov ah,9h;使用int21 9号功能 ds:dx为字符串首地址,$为结束符
int 21h
ENDM
NUMBER MACRO;输入学生数
out_str show10
call input
lea si,count
mov word ptr [si],bx;人数存在count
ENDM
change_line MACRO;换行
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
ENDM
start:
mov ax,data
mov ds,ax
NUMBER
call menu
start0:
change_line
out_str shows
mov ah,01h
int 21h;输入选择
sub al,30h
cmp al,0
jb start0
cmp al,6
ja start0
dec al
shl al,1
xor ah,ah
mov bx,ax
change_line
call FUN[bx];调用功能
jmp start0
mov ax,4c00h
int 21h
menu PROC
change_line
out_str showmenu
out_str showmenu0
ret
menu ENDP
function1 PROC
nop
ret
function1 ENDP
function2 PROC
nop
ret
function2 ENDP
function3 PROC
nop
ret
function3 ENDP
function4 PROC
nop
ret
FUNCTION4 ENDP
function5 PROC
nop
ret
function5 ENDP
function6 PROC
out_str show0
mov ah,4ch
int 21h
ret
function6 ENDP
input PROC ;输入数字 bx返回十进制
mov bx,0
num:
mov ah,1;输入一位字符到al
int 21h;int 21 1号功能 键盘输入并回显 输入字符存在al上
sub al,30h;数字字符ascii转换为10进制数字
jb exit
cmp al,9
ja exit;不是数字直接退出
cbw
xchg ax,bx
mul count2[0]
xchg ax,bx
add bx,ax
jmp num;输入为数字时,继续循环 空格或enter退出循环
exit:
ret
input ENDP
code ends
end start
信息录入
信息录入可以使用int21 的9号功能,在查询模块中学号和姓名模块我用的就是9号功能,当时信息录入用的2号功能,麻烦,建议使用9号,这里也懒得改了,想用9号功能参考查询模块中学号和姓名输入的用法
assume cs:code,ds:data
data segment
FUN dw function1
show10 db 'please enter the number of students:','$'
show11 db 'id name comgrade fingrade',0dh,0ah,'$';录入学生信息的提示,0dh enter 0ah 换
行
show2 db ' ','$'
count dw 0;存放录入学生人数
count1 dw 4,12,4,2;对应要输入信息循环次数
count2 dw 10;用于将得到的数字字符转成十进制时,/10操作 一个常数
count3 dw 0;用来记录输入名字时偏移地址信息
count4 dw 0;记录第i人录入名字
SNO dw 100 dup(?)
SNAME db 200 dup(' ')
COMGRADE dw 100 dup(?)
FINGRADE dw 100 dup(?)
TOLGRADE dw 100 dup(?)
RANK dw 100 dup(?)
grade_addr dw 10 dup(0);grade相对地址
name_addr dw 10 dup(0);name相对地址
str_num db 20 dup(0);放name长度
data ends
code segment
out_str MACRO Y;输出字符串 宏定义
lea dx,Y;将Y地址赋给dx
mov ah,9h;使用int21 9号功能 ds:dx为字符串首地址,$为结束符
int 21h
ENDM
NUMBER MACRO;输入学生数
out_str show10
call input
lea si,count
mov word ptr [si],bx;人数存在count
ENDM
change_line MACRO;换行
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
ENDM
start:
mov ax,data
mov ds,ax
NUMBER
call FUN[0]
lea si,SNO
lea di,SNAME
lea bx,COMGRADE
lea dx,FINGRADE
mov ax,4c00h
int 21h
function1 PROC near;功能1part 输入学生的学号 平时成绩
out_str show11
lea si,count;lea 将count偏移地址送入si中
mov cx ,word ptr [si]
mov si,0
one:
call input;将id存入
mov word ptr SNO[si],bx;
out_str show2
call input1;存名字
out_str show2
call input;存16次作业成绩
mov word ptr COMGRADE[si],bx
out_str show2
call input;存大作业成绩
mov word ptr FINGRADE[si],bx
out_str show2
mov RANK[si],cx
add si,2
change_line
loop one
ret
function1 ENDP
input PROC near;输入数字 bx返回十进制
mov bx,0
num:
mov ah,1;输入一位字符到al
int 21h;int 21 1号功能 键盘输入并回显 输入字符存在al上
sub al,30h;数字字符ascii转换为10进制数字
jb exit
cmp al,9
ja exit;不是数字直接退出
cbw
xchg ax,bx
mul count2[0]
xchg ax,bx
add bx,ax
jmp num;输入为数字时,继续循环 空格或enter退出循环
exit:
ret
input ENDP
input1 PROC near;输入名字 名字用s
mov bx,count3[0] ;保存下次存放name的偏移地址
mov di,count4[0];记录第i人
mov bp,di
add bp,bp
mov name_addr[bp],bx;记录每个名字的起始地址
mov grade_addr[bp],di;成绩相对地址
char1:
mov ah,1;
int 21h;
; cmp ah,08h;如果是backspace
; je backspace1
cmp al,61h
jb exit1
cmp al,7ah
ja exit1;不是小写字母跳转
mov SNAME[bx],al
inc bx
jmp char1;输入为小写字母继续循环,空格或enter退出循环
exit1:
mov SNAME[bx],'$';结束符,用于sort输出
inc count4[0]
sub bx,count3[0]
mov str_num[di],bl;名字长度
inc bx
add count3[0],bx
ret
input1 ENDP
code ends
end start
成绩计算
assume cs:code,ds:data
data segment
COMGRADE dw 1500,1550,1580,1600;1500/160040=1500/40
FINGRADE dw 95,92,96,94 ;95/10060=95*3/5
TOLGRADE dw 0,0,0,0
cal_parm db 40,3,5
count dw 4
data ends
code segment
start:
mov ax,data
mov ds,ax
call function2
mov ax,4c00h
int 21h
function2 PROC
push count[0]
push si
push bx
mov si,0
mov bx,0
cal_one:
mov ax,COMGRADE[si]
div cal_parm[0]
mov ah,0
add TOLGRADE[bx],ax
mov ax,FINGRADE[si]
mul cal_parm[1]
div cal_parm[2]
mov ah,0
add TOLGRADE[bx],ax
add si,2
add bx,2
dec count[0]
cmp count[0],0
ja cal_one
pop count[0]
pop si
pop bx
ret
function2 ENDP
code ends
end start
排序
assume cs:code,ds:data
data segment
count dw 5
count3 dw 0;用来记录输入名字时偏移地址信息
count4 dw 0;记录第i人录入名字
show2 db ' ','$'
show3 db 'id name comgra fingra tolal rank',0dh,0ah,'$'
SNO dw 1001,1002,1003,1004,1005
SNAME db 'jack$','mary$','lucy$','smith$','tomy$'
COMGRADE dw 1500,1550,1580,1590,1600
FINGRADE dw 95,92,96,98,94
TOLGRADE dw 94,93,96,97,96
TOLGRADE1 dw 94,93,96,97,96;副本
RANK dw 5,4,3,2,1;排名同时也包含这各成绩的相对地址
grade_addr dw 0,1,2,3,4;grade相对地址
name_addr dw 0,5,10,15,21;name相对地址
divition dw 1000,100,10,1
results db 0,0,0,0,'$'
str_num db 4,4,4,5,3;20 dup(0)放name长度
data ends
code segment
out_str MACRO Y;输出字符串 宏定义
lea dx,Y;将Y地址赋给dx
mov ah,9h;使用int21 9号功能 ds:dx为字符串首地址,$为结束符
int 21h
ENDM
change_line MACRO;换行
push dx
push ax
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
pop ax
pop dx
ENDM
start:
mov ax,data
mov ds,ax
call function3
lea si,grade_addr
mov ax,4c00h
int 21h
function3 PROC
mov si,0;设置参数
mov cx,count[0]
dec cx
mov ax,0
loopOne:
push cx
push si
loopTwo:
mov ax,TOLGRADE1[si]
cmp ax,TOLGRADE1[si+2]
jna next
xchg ax,TOLGRADE1[si+2]
xchg ax,TOLGRADE1[si]
mov ax,grade_addr[si];交换地址
xchg ax,grade_addr[si+2]
xchg ax,grade_addr[si]
next:
add si,2
loop loopTwo
pop si;
pop cx;
loop loopOne
mov cx,count[0]
mov si,0
out_str show3
sort_print:
mov di,grade_addr[si]
add di,di
mov ax,SNO[di];id
call output
out_str show2
lea dx,SNAME
add dx,name_addr[di]
mov ah,09h
int 21h;name
out_str show2
mov ax,COMGRADE[di];comgrade
call output
out_str show2
mov ax,FINGRADE[di];fingrade
call output
out_str show2
mov ax,TOLGRADE[di];total
call output
out_str show2
mov ax,RANK[si];rank
call output
change_line
add si,2
loop sort_print
ret
function3 ENDP
output PROC;输出数字
push si
push di
push cx
mov si,offset divition
mov di,offset results
mov cx,4
cal:
mov dx,0
div word ptr [si];ax/1000
add al,30h
mov byte ptr [di],al;将结果从高位到低位存入results
inc di
add si,2
mov ax,dx;余数给回
loop cal
mov cx,3;检测数据前3位是否是0,不是则显示
mov di,offset results
nz:
cmp byte ptr [di],'0'
jne print
inc di
loop nz
print:
mov dx,di
mov ah,9h
int 21h
pop cx
pop di
pop si
ret
output ENDP
code ends
end start
查询
assume cs:code,ds:data
data segment
show40 db 'select id(1) or name(2) to query:','$'
show41 db 'please enter id:','$'
show42 db 'please enter name:','$'
show43 db 'cannot find such id/name',0dh,0ah,'$'
show44 db 'total grade:','$'
divition dw 1000,100,10,1
results db 0,0,0,0,'$'
selection dw 0;查询选择
count dw 4;存放录入学生人数
count1 dw 4,12,4,2;对应要输入信息循环次数
count2 dw 10;用于将得到的数字
count3 dw 0;用来记录输入名字时偏移地址信息
count4 dw 0;记录第i人录入名字
SNO dw 1001,1002,1003,1004
SNAME db 'jack','mary','lucy','smith'
COMGRADE dw 1500,1550,1580,1600;
FINGRADE dw 95,92,96,94
TOLGRADE dw 94,93,96,96
RANK db 4,3,1,1
str1 db 10;最大长度
db 0;接收字符串的实际长度
db 10 dup(0);字符串
str_num db 4,4,4,5;20 dup(0)放name长度 用于查询名字时,长度比较
data ends
code segment
change_line MACRO;换行
push dx
push ax
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
pop ax
pop dx
ENDM
out_str MACRO Y;输出字符串 宏定义 感觉就像函数
lea dx,Y;将Y地址赋给dx
mov ah,9h;使用int21 9号功能 ds:dx为字符串首地址,$为结束符
int 21h
ENDM
start:
mov ax,data
mov ds,ax
mov es,ax
call function4
mov ax,4c00h
int 21h
function4 PROC
mov cx,count[0]
mov si,0
mov di,0
out_str show40
call input;输入查询选择 1 id 2 name
cmp bx,1
je ID_SEQ
cmp bx,2
je NAME_QUE
cmp bx,1
jb QUE_QUIT1
cmp bx,2
jb QUE_QUIT
ID_SEQ:
mov selection[0],1
out_str show41
call input;输入学号
id_cmp:
cmp SNO[si],bx
je QUE_QUIT;相等输出所有信息
add si,2
loop id_cmp
out_str show43;未找到匹配的id或名字,输出提醒
jmp QUE_QUIT1
NAME_QUE:
mov selection[0],2
out_str show42
mov bx,0
mov bp,0
push count[0]
lea dx,str1
mov ah,10;输入字符串到str1
int 21h
change_line
xor ah,ah;清0
mov al,str1[1];输入字符串实际长度
STR_CMP:
cmp al,str_num[bp];如果输入字符串与名字长度不同,则直接跳过
jne len_dif
lea si,SNAME[bx]
lea di,str1[2]
mov cx,ax
cld
repe cmpsb
je QUE_QUIT;相等跳到QUE_NAME_QUIT
len_dif:
add bl,str_num[bp]
inc bp
dec count[0]
cmp count[0],0
ja STR_CMP
pop count[0]
out_str show43;未找到匹配的id或名字,输出提醒
jmp QUE_QUIT1
QUE_QUIT:
out_str show44
.if selection[0]==1
mov ax,TOLGRADE[si]
.endif
.if selection[0]==2
add bp,bp
mov ax,TOLGRADE[bp]
.endif
call output;输出成绩
change_line
QUE_QUIT1:
ret
function4 ENDP
input PROC near;输入数字 bx返回十进制
mov bx,0
num:
mov ah,1;输入一位字符到al
int 21h;int 21 1号功能 键盘输入并回显 输入字符存在al上
sub al,30h;数字字符ascii转换为10进制数字
jb exit
cmp al,9
ja exit;不是数字直接退出
cbw
xchg ax,bx
mul count2[0]
xchg ax,bx
add bx,ax
jmp num;输入为数字时,继续循环 空格或enter退出循环
exit:
ret
input ENDP
input1 PROC near;输入名字 名字用s
mov bx,count3[0] ;保存下次存放name的偏移地址
mov di,count4[0];记录第i人
char1:
mov ah,1;
int 21h;
; cmp ah,08h;如果是backspace
; je backspace1
cmp al,61h
jb exit1
cmp al,7ah
ja exit1;不是小写字母跳转
mov SNAME[bx],al
inc bx
jmp char1;输入为小写字母继续循环,空格或enter退出循环
exit1:
mov str_num[di],bl;记录每个名字的长度
inc count4[0]
mov count3[0],bx
ret
input1 ENDP
output PROC;输出数字
mov si,offset divition
mov di,offset results
mov cx,4
cal:
mov dx,0
div word ptr [si];ax/1000
add al,30h
mov byte ptr [di],al;将结果从高位到低位存入results
inc di
add si,2
mov ax,dx;余数给回
loop cal
mov cx,3;检测数据前3位是否是0,不是则显示
mov di,offset results
nz:
cmp byte ptr [di],'0'
jne print
inc di
loop nz
print:
mov dx,di
mov ah,9h
int 21h
ret
output ENDP
code ends
end start
显示最高分,最低分,平均分
assume cs:code,ds:data
data segment
TOLGRADE dw 78,89,95,65,87,96,85,72
count dw 8
count5 dw 0,0,0,0,0,0,100,'$';前4个保存各分段人数 后3个保存平均分,最高分,最低分
show51 db ' 0-59:','$'
show52 db '60-79:','$'
show53 db '80-89:','$'
show54 db '90-100:','$'
show61 db 'avrage grade:','$'
show62 db 'highest grade:','$'
show63 db 'lowest grade:','$'
divition dw 1000,100,10,1
results db 0,0,0,0,'$'
data ends
code segment
out_str MACRO Y;输出字符串 宏定义 感觉就像函数
lea dx,Y;将Y地址赋给dx
mov ah,9h;使用int21 9号功能 ds:dx为字符串首地址,$为结束符
int 21h
ENDM
change_line MACRO;换行
push dx
push ax
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
pop ax
pop dx
ENDM
start:
mov ax,data
mov ds,ax
call function5
call function6
mov ax,4c00h
int 21h
function5 PROC
mov cx,count[0]
mov ax,0
lea di,TOLGRADE
push cx
push di
total_grade:
mov bx,[di]
.if bx>count5[10]
mov count5[10],bx;最大值
.endif
.if bx<count5[12]
mov count5[12],bx;最小值
.endif
add ax,bx;成绩总和放在ax里
add di,2
loop total_grade
xor dx,dx
div count[0]
mov count5[8],ax;存入平均分
pop di
pop cx
four_grade:
cmp word ptr [di],60
jb L1
cmp word ptr [di],80
jb L2
cmp word ptr [di],90
jb L3
inc count5[6];90-100分段人数
jmp sta_exit
L1:
inc count5[0];0-59
jmp sta_exit
L2:
inc count5[2];60-79
jmp sta_exit
L3:
inc count5[4];80-89
jmp sta_exit
sta_exit:
add di,2
loop four_grade
out_str show51
mov ax,count5[0]
call output
change_line
out_str show52
mov ax,count5[2]
call output
change_line
out_str show53
mov ax,count5[4]
call output
change_line
out_str show54
mov ax,count5[6]
call output
change_line
ret
function5 ENDP
function6 PROC
out_str show61
mov ax,count5[8]
call output
change_line
out_str show62
mov ax,count5[10]
call output
change_line
out_str show63
mov ax,count5[12]
call output
change_line
ret
function6 ENDP
output PROC;输出数字 输入参数 ax 存需要显示的数字
mov si,offset divition
mov di,offset results
mov cx,4
cal:
mov dx,0
div word ptr [si];ax/1000
add al,30h
mov byte ptr [di],al;将结果从高位到低位存入results
inc di
add si,2
mov ax,dx;余数给回
loop cal
mov cx,3;检测数据前3位是否是0,不是则显示
mov di,offset results
nz:
cmp byte ptr [di],'0'
jne print
inc di
loop nz
print:
mov dx,di
mov ah,9h
int 21h
ret
output ENDP
code ends
end start