大作业.asm

来自「该程序用于实现学生数据库管理」· 汇编 代码 · 共 961 行 · 第 1/2 页

ASM
961
字号
TITLE   8086 Code Template (for EXE file)

;       AUTHOR          emu8086
;       DATE            ?
;       VERSION         1.00
;       FILE            ?.ASM

; 8086 Code Template

; Directive to make EXE output:
       #MAKE_EXE#

DSEG    SEGMENT 'DATA'
segflag    db   0
flag       db   0
scochanged db   4 dup (0)
foundflag  db   0;寻找时的找到标志
x          db   24;每个学生信息所占用的空间
rateinfo   db   20 dup(0);排序时用来存储各学生的首地址
y          db   10
count      db   0;已存在的学生数目
segn       db   6 dup(0)
null	   db   '   $';输出学生各数据间的间隔	   
prompt     db   13,10,'1.write'
           db   13,10,'2.edit'
           db   13,10,'3.delete'
           db   13,10,'4.search'
           db   13,10,'5.sort'
           db   13,10,'6.statistic'
           db   13,10,'7.display'
           db   13,10,'8.exit system',13,10,'$'
editinfo   db   13,10,'1.edit name'
	   db   13,10,'2.edit score1'
	   db   13,10,'3.edit score2'
	   db   13,10,'4.edit score3'
	   db   13,10,'5.return to main menu',13,10,'$'
InpErr     db   13,10,'input error,please input again',13,10,'$'
Inname     db   13,10,'please input the name   :$'
Inscore1   db   13,10,'please input the score1 :$'
Inscore2   db   13,10,'please input the score2 :$'
Inscore3   db   13,10,'please input the score3 :$'
notfound   db   13,10,'the student does not exist',13,10,'$'
srhname    db   'input the name of student wanted',13,10,'$'
ChoSort    db   13,10,'1.sort by score1'
	   db   13,10,'2.sort by score2'
	   db   13,10,'3.sort by score3'
	   db   13,10,'4.sort by total score'
	   db   13,10,'5.return to main menu',13,10,'$'
ChoSta     db   13,10,'1.single score average'
	   db   13,10,'2.total score average'
	   db   13,10,'3.single score segments'
	   db   13,10,'4.total score segments'
	   db   13,10,'5.return to main menu',13,10,'$'   
fullmark   db   '100$'
deleted    db   13,10,'student information deleted',13,10,'$'
stasingle1 db   13,10,'score1 average   $'
stasingle2 db   13,10,'score2 average   $'
stasingle3 db   13,10,'score3 average   $'
staall     db   13,10,'total score average    $'
sumsegc    db   13,10,'total score segment$'
score1seg  db   13,10,'score1 segment :',13,10,'$'
score2seg  db   13,10,'score2 segment :',13,10,'$'
score3seg  db   13,10,'score3 segment :',13,10,'$'
sinsegment db   '0-59 60-69 70-79 80-89 90-99 100',13,10,'$'
sumsegment db   13,10,'0--180--210--240--270--299--300',13,10,'$'  
findcho    db   13,10,'1.look for someone'
	   db   13,10,'2.see who failed'
	   db   13,10,'3.return to main menu',13,10,'$'
rating     db   13,10,'rating $'  
branch_table  dw  wri
              dw  edi
              dw  del
              dw  sea
              dw  sor
              dw  sta
              dw  dis
              dw  exi
name          db  15,0,15 dup(?);名字缓冲区
student       db  20 dup(15 dup(?),5 dup(?),4 dup(?));前15位为姓名,后面的5位为各科成绩及总分,后四位为各科排名       

DSEG    ENDS

SSEG    SEGMENT STACK   'STACK'
        DW      100h    DUP(?)
SSEG    ENDS

CSEG    SEGMENT 'CODE'

;*******************************************

START   PROC    FAR
; Store return address to OS:
    PUSH    DS
    MOV     AX, 0
    PUSH    AX

; set segment registers:
    MOV     AX, DSEG
    MOV     DS, AX
    MOV     ES, AX
mov ch,0
repeat:	lea dx,prompt
	mov ah,9
	int 21h
	mov ah,01h
	int 21h
	cmp al,31h
	jl  error
	cmp al,38h
	jg  error
	sub al,30h
	mov ah,0
	shl ax,1
	mov si,ax
	jmp branch_table[si-2]
wri:    sub ah,ah
        mov al,count
        mul x
        mov bx,ax;bx的内容为要写入的学生的首地址
        inc count
        call write
        jmp  repeat
edi:    call edit
        jmp  repeat
del:    call delete
        jmp repeat
sea:    call search
        jmp repeat
sor:    call sort
        jmp repeat
sta:    call statistic
        jmp repeat
dis:    call display
        jmp repeat
error:  lea dx,InpErr
        mov ah,9
        int 21h
        jmp repeat
exi:    mov ah,4ch  
	int 21h    
    RET
START   ENDP

Wname proc near
        lea dx,Inname
        mov ah,09h
        int 21h 
        lea dx,name
        mov ah,0ah
        int 21h
        mov si,2;name的前两个字节存放输入最大字符数和实际输入字符数
        mov cl,name+1;name+1存的是实际输入字符数
again:  mov al,name[si]
        mov student[bx][si-2],al;把name的内容赋给student
        inc si
        loop again
        mov student[bx][si-2],'$'
        ret
Wname endp

Wscore1 proc near
        lea dx,inscore1
        mov ah,09h
        int 21h
        mov si,15
        call Wscore
        ret
Wscore1 endp


Wscore2 proc near
        lea dx,inscore2
        mov ah,09h
        int 21h
        mov si,16
        call Wscore
        ret
Wscore2 endp

Wscore3 proc near
        lea dx,inscore3
        mov ah,09h
        int 21h
        mov si,17
        call Wscore
        ret
Wscore3 endp

Wscore proc near
        mov dx,0
circle: mov ah,01h
        int 21h
        cmp al,0dh
        je over;输入成绩,回车为结束标志
        sub al,30h
        xchg ax,dx
        mul y;y=10
        add al,dl
        mov dx,ax
        jmp circle
over:   mov student[bx][si],dl;此时dl的内容为把输入的字符串转换成的成绩
	mov scochanged[si-15],1
	mov scochanged[3],1
        ret
Wscore endp

Wsum proc near
        push si
        push cx
        mov si,15
        mov ax,0
        mov cx,3
        mov ah,0
cal:    add al,student[bx][si];计算各科成绩和
        jnc goon
        mov ah,1
goon:   inc si
        loop cal
        mov student[bx+18],al
        mov student[bx+19],ah 
        mov scochanged[3],1
        pop cx
        pop si
        ret
Wsum endp

write proc near
        call Wname        
        call Wscore1
        call Wscore2
        call Wscore3
        call Wsum               
        ret        
write endp

ctrlf proc near
	;该子程序用来打出回车
        push dx
        push ax
	mov dl,0dh
	mov ah,2
	int 21h
	mov dl,0ah
	mov ah,2
	int 21h
	pop ax
	pop dx
	ret
ctrlf endp

space proc near
	;该子程序用来打出三个空格
        push ax
        push dx
	lea dx,Null
	mov ah,9
	int 21h
 	pop dx
 	pop ax
 	ret
space endp	

edit proc near
        call find;按名字查找
        cmp foundflag,0;判断是否找到
        je exit
recarry:lea dx,editinfo
        mov ah,09h
        int 21h
        mov ah,1
        int 21h
        sub al,30h
        js error1
        cmp al,5
        jg error1
        cmp al,1
        je rename
        cmp al,2
        je rescore1
        cmp al,3
        je rescore2
        cmp al,4
        je rescore3
        jmp exit
Rename: call Wname
        jmp recarry
rescore1:call Wscore1
        call Wsum
 	jmp recarry
rescore2:call Wscore2
	call Wsum
 	jmp recarry 
rescore3:call Wscore3
	call Wsum
 	jmp recarry
error1: lea dx,InpErr
        mov ah,9
        int 21h
        jmp recarry
exit:	mov foundflag,0
        ret        
edit endp

delete proc near
	push si
	push bx
	call find;按名字查找
	cmp foundflag,0;判断是否找到
	je exit2
	;下面代码实现的是把已删除学生后面的学生信息全部上移
	mov cl,count
	mov al,bl
	mov ah,0
	div x
	sub cl,al
move1:	mov al,x
	mov si,ax
	dec si
move:	add bl,x
	mov al,student[bx][si]
	sub bl,x
	mov student[bx][si],al
	dec si
	jns move
	add bl,x
	loop move1
	dec count
	lea dx,deleted
	mov ah,9
	int 21h		
	mov foundflag,0
	mov cl,4
	mov si,0
reflag: mov scochanged[si],1
	inc si
	loop reflag	
exit2:	pop bx
	pop si	
	ret
delete endp 
                       
find proc near
	cmp count,0
	je Nfound;无学生记录直接跳出
        call ctrlf
	lea dx,srhname
        mov ah,9
        int 21h
        lea dx,name
        mov ah,0ah
        int 21h
        mov dl,name+1;把输入的字符串长度存入dl
        sub dh,dh
        mov cl,count
        mov di,dx
        mov bx,0
 Rseek: cmp student[bx][di],'$';判断字符串长度是否相等
	jne keepon
seek:   mov al,name[di+1]
        cmp student[bx][di-1],al;从字符串的最后一个字符开始比较
        jne KeepOn
        dec di
        jnz seek
        jmp found;字符串相等
KeepOn: add bl,x
        loop Rseek
Nfound: lea dx,notfound
        mov ah,9
        int 21h
        mov foundflag,0
        jmp quit
found:  mov foundflag,1
	call ctrlf
	call output;输出找到的学生的信息
	mov ah,0
	call outscore
quit:   ret;bx返回查找结果
find endp

search proc near
resea:	lea dx,findcho
	mov ah,9
	int 21h
	mov ah,1
	int 21h 
	sub al,30h
	js serror
	cmp al,1
	je lookfor
	cmp al,2
	je sfailed
	cmp al,3
	je seaquit
	jmp serror
lookfor:call seefor
	jmp resea
sfailed:call failed
	jmp resea	
serror: lea dx,inperr
	mov ah,9
	int 21h	
        jmp resea
seaquit:ret
search endp	

seefor proc near
	call find
	cmp foundflag,0
	je seequit
	lea dx,rating
	mov ah,9
	int 21h
	mov di,20
	cmp scochanged[di-20],0
	je rate1
	call sortsco1
	mov scochanged[di-20],0
	call inrate
rate1:	call outrate
	inc di
	cmp scochanged[di-20],0
	je rate2
	call sortsco2
	mov scochanged[di-20],0
	call inrate
rate2:	call outrate
	inc di
	cmp scochanged[di-20],0
	je rate3
	call sortsco3
	mov scochanged[di-20],0
	call inrate
rate3:	call outrate
	inc di
	cmp scochanged[di-20],0
	je ratea
	call sortscoa
	mov scochanged[di-20],0
	call inrate
ratea:	call outrate
seequit:ret
seefor endp

inrate proc near
	push bx
	mov cl,count
	mov si,1
ratein:	mov bl,rateinfo[si-1]
	mov ax,si
	mov student[bx][di],al
	inc si
	loop ratein
	pop bx
	ret
inrate endp

outrate proc near
	mov cl,1
	call sinscore;输出学生的排名
	ret	
outrate endp
	
failed	proc near
	push si
	lea dx,score1seg
	mov ah,9
	int 21h
	mov si,15
	call outfname
	lea dx,score2seg
	mov ah,9
	int 21h
	inc si
	call outfname
	lea dx,score3seg
	mov ah,9
	int 21h
	inc si
	call outfname
	pop si
	ret

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?