【无标题】汇编实验-学生成绩管理系统

实现功能:

  • 键盘输入学生信息,包括学号,姓名,成绩
  • 通过学号\姓名查询成绩
  • 成绩排序
  • 显示每个分段的人数(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
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值