📄 main.asm
字号:
;main.asm文件为系统的主文件,包括主模块在内。功能有显示(输出)数据内容、计算总分、删除和响应键盘等
include macro.asm ;macro.asm宏文件
extrn start:far,new:far,load:far,save:far,ifc:far,input:far,del:far,sort:far,find:far,help:far
public res,pag,row,line,tot,pri,cur,flag,tota,findf,frow,fd,fstart
result struc ;成绩单结构,由学号(nam,13字节)、姓名(num,7字节)、汇编语言成绩(asm,4字节)、组成原理成绩(ct,4字节)、操作系统成绩(os,4字节)和总分(total,4字节)五部分构成,共44字节
nam db 11,?,11 dup('$')
num db 7,?,7 dup('$')
asm db 4,?,4 dup('$')
ct db 4,?,4 dup('$')
os db 4,?,4 dup('$')
total db 3 dup(' '),'$'
result ends
stacksg segment stack 's'
dw 128 dup('s')
stacksg ends
data segment public
res result 100 dup(<>) ;成绩单结构数组res
pri db 100 dup(0) ;优先级数组pri,用于判断光标当前位置是否达到可以输入的优先级
cur db 1 ;输入位置的行号
tot db 1 ;总条目数(初始唯一,实际比总条目数大1)
flag db 0 ;输入标志(可以输入为1,否则为0)
findf db 0 ;查找标志(找到为1,否则为0)
fstart db 1 ;查找开始行号(1——tot)
frow db ? ;查找到的数据的行号
n db ?
row db 3 ;光标行号(3,5,7,...,21)
line db 25 ;光标列号(25,36,43,47,51)
drow db ? ;欲显示数据的行号(3,5,7,...,21)
dline db ? ;欲显示数据的列号(25,36,43,47,51)
pag db 0 ;页号(0——10)
tota dw 100 dup(0) ;总分数组
acc dw ? ;计算总分的累加器
fd dw -1 ;文件句柄
data ends
code segment
main proc far
assume cs:code,ds:data,es:data,ss:stacksg
mov ax,data
mov ds,ax
mov es,ax
stt: call far ptr start ;显示开始画面
draw: call far ptr ifc ;绘制表格
call disp ;显示数据,几乎每项功能调用之后都要调用绘制表格和显示数据
cursor:
mov ah,2
mov bh,0
mov dh,row
mov dl,line
int 10h ;光标定位
mov findf,0
mov fd,-1
cj: mov ah,0 ;响应键盘
int 16h
cmp ah,01h ;ESC 退出
jz exit
cmp ah,1ch ;Enter 输入(插入)
jz ipt
cmp ah,3bh ;F1 新建(刷新)
jz nf
cmp ah,3ch ;F2 读取文件
jz lf
cmp ah,3dh ;F3 储存文件
jz sf
cmp ah,3eh ;F4 排序
jz srt
cmp ah,3fh ;F5 查找
jz fnd
cmp ah,40h ;F6 删除(输入行)
jz del1
cmp ah,41h ;F7 帮助
jz hlp
cmp ah,42h ;F8 退出
jz exit
cmp ah,43h ;F9 排序
jz srt
cmp ah,44h ;F10 查找
jz fnd
cmp ah,52h ;Insert 输入(插入)
jz ipt
cmp ah,47h ;Home 开始画面
jz stt
cmp ah,53h ;Delete 删除(当前行)
jz del2
cmp ah,4fh ;End 退出
jz exit
cmp ah,39h ;Space 输入(插入)
jz ipt
cmp ah,31h ;n 新建(刷新)
jz nf
cmp ah,26h ;l 读取文件
jz lf
cmp ah,1fh ;s 存储文件
jz sf
cmp ah,20h ;d 删除(输入行)
jz del1
cmp ah,21h ;f 查找
jz fnd
cmp ah,23h ;h 帮助
jz hlp
cmp ah,0eh ;Backspace 退格(上一格,同坐键)
jz left
cmp ah,0fh ;Tab 跳格(下一格,同右键)
jz right
cmp ah,48h ;UpArrow 向上
jz up
cmp ah,50h ;DownArrow 向下
jz down
cmp ah,4bh ;LeftArrow 向左
jz left
cmp ah,4dh ;RightArrow 向右
jz right
cmp ah,49h ;PgUp 上翻页
jz pu
cmp ah,51h ;PgDn 下翻页
jz pd
jmp sta ;No Operation 无操作
ipt: mov al,row ;输入(插入),计算当前行号(pag*10+row/2)及在结构res中的位置[(pag*10+row/2-1)*44]
xor ah,ah
mov bl,2
div bl
mov cl,al
mov al,pag
mov bl,10
mul bl
add al,cl
mov cur,al
cmp al,tot
ja sta
dec al
mov bl,44
mul bl
lea bp,res
add bp,ax
mov flag,1
call far ptr input ;输入
cmp flag,0 ;若输入标志为0,则不输入
jz cj
cmp line,36 ;判断当前列所在格的类型
ja i2
i1: jmp draw
i2: call sum ;若为分数格(line>36),则计算总分
jmp draw
nf: call far ptr new ;新建
jmp draw
lf: call far ptr load ;读取
jmp draw
sf: call far ptr save ;存储
jmp draw
srt: call far ptr sort ;排序
jmp draw
fnd: call far ptr find ;查找
jmp draw
del1: call far ptr del ;删除输入行
jmp draw
del2: call d2 ;删除当前行
jmp draw
hlp: call far ptr help ;帮助
jmp draw
up: cmp row,3 ;向上(光标上移一行)
jz uj
sub row,2
jmp cursor
uj: cmp pag,0 ;光标以至首页的第一行,发警告音提示
jz sta
mov row,21
dec pag
jmp draw
down: cmp row,21 ;向下(光标下移一行)
jz dj
add row,2
jmp cursor
dj: cmp pag,9 ;光标以至末页的最后一行,发警告音提示
jz sta
mov row,3
inc pag
jmp draw
left: cmp line,51 ;向左(光标左移一格)
jz l1
cmp line,47
jz l2
cmp line,43
jz l3
cmp line,36
jz l4
cmp line,25
jz lj1
l1: mov line,47
jmp cursor
l2: mov line,43
jmp cursor
l3: mov line,36
jmp cursor
l4: mov line,25
jmp cursor
lj1: cmp row,3 ;光标已至每行最左一格,移至上行最右一个
jz lj2
sub row,2
mov line,51
jmp cursor
lj2: cmp pag,0 ;光标已至首页的第一行最左一格,发警告音提示
jz sta
dec pag
mov row,21
mov line,51
jmp draw
right: cmp line,25 ;向右(光标右移一格)
jz r1
cmp line,36
jz r2
cmp line,43
jz r3
cmp line,47
jz r4
cmp line,51
jz rj1
r1: mov line,36
jmp cursor
r2: mov line,43
jmp cursor
r3: mov line,47
jmp cursor
r4: mov line,51
jmp cursor
rj1: cmp row,21 ;光标已至每行最右一格,移至下行最左一个
jz rj2
add row,2
mov line,25
jmp cursor
rj2: cmp pag,9 ;光标已至末页的最后一行最右一格,发警告音提示
jz sta
inc pag
mov row,3
mov line,25
jmp draw
pu: cmp pag,0 ;上翻页(若光标已至首页,发警告音提示)
jz sta
dec pag
jmp draw
pd: cmp pag,9 ;下翻页(若光标已至末页,发警告音提示)
jz sta
inc pag
jmp draw
sta: mov ah,14 ;警告音,返回响应键盘处
mov al,7
mov bh,0
int 10h
jmp cj
exit: mov ax,4c00h
int 21h
main endp
disp proc far ;显示(输出)数据子函数disp
mov drow,3 ;置显示的光标到首行首列
mov dline,25
mov al,pag
mov bl,10
mul bl
mov bl,44
mul bl
lea bx,res ;计算开始显示的数据在结构中的位置(res+pag*10*44)
add bx,ax
mov n,0
lop: cmp n,10 ;每页显示10条数据
jz quit
dnam: mov dline,25
lea bp,[bx].nam+2
mov cl,[bx].nam+1
xor ch,ch
dispd drow,dline
dnum: mov dline,36
lea bp,[bx].num+2
mov cl,[bx].num+1
xor ch,ch
dispd drow,dline
dasm: mov dline,43
lea bp,[bx].asm+2
mov cl,[bx].asm+1
xor ch,ch
dispd drow,dline
dct: mov dline,47
lea bp,[bx].ct+2
mov cl,[bx].ct+1
xor ch,ch
dispd drow,dline
dos: mov dline,51
lea bp,[bx].os+2
mov cl,[bx].os+1
xor ch,ch
dispd drow,dline
dtot: mov dline,55
lea bp,[bx].total
mov cl,3
xor ch,ch
dispd drow,dline
add drow,2
add bx,44
inc n
jmp lop
quit: ret
disp endp
sum proc far ;计算总分子函数sum
mov acc,0 ;总分累加器置0
lea si,[bp].asm
call td ;计算汇编语言成绩
add acc,ax
lea si,[bp].ct
call td ;计算组成原理成绩
add acc,ax
lea si,[bp].os
call td ;计算操作系统成绩
add acc,ax
mov al,row ;计算当前行号(pag*10+row/2)及在结构res中的位置[(pag*10+row/2-1)*44]
xor ah,ah
mov bl,2
div bl
mov cl,al
mov al,pag
mov bl,10
mul bl
add al,cl
dec al
mov dl,al
xor dh,dh
mov bl,44
mul bl
lea si,tota ;将总分写入总分数组tota,位置与该条数据在成绩单结构数组中的位置相同
add si,dx
add si,dx
mov bx,acc
mov [si],bx
lea si,[bp].total
mov byte ptr [si],' '
mov byte ptr [si+1],' '
mov byte ptr [si+2],' '
mov byte ptr [si+3],'$'
add si,3
call ta ;将总分转换为字符
ret
sum endp
td proc far ;字符转换为10进制数的子函数td
xor al,al
mov bl,10
mov cl,[si+1] ;字符串长度
cmp cl,0
jz td3
dec cl
xor ch,ch
add si,2
cmp cl,0
jz td2
td1: add al,[si]
sub al,30h
mul bl ;从字符串首位至倒数第二位,每位均计入al,并减30h('0'的ASCII值),再乘10
inc si
loop td1
td2: add al,[si] ;最后一位数加入al,并减30h
sub al,30h
xor ah,ah
td3: ret
td endp
ta proc ;10进制数转换为字符串的子函数ta
mov ax,acc
mov bl,10
ta1: dec si ;用数字除以10,余数为低位,商作为下一次的被除数
div bl
add ah,30h
mov [si],ah
xor ah,ah
cmp al,0
jnz ta1
ta3: ret
ta endp
d2 proc ;删除当前行的子函数d2
mov al,row ;计算当前行号(pag*10+row/2)及在结构res中的位置[(pag*10+row/2-1)*44]
xor ah,ah
mov bl,2
div bl
mov cl,al
mov al,pag
mov bl,10
mul bl
add al,cl
mov dl,al
xor dh,dh
dec al
mov bl,44
mul bl
lea bp,res
add bp,ax
lopd2: cmp tot,dl ;对从当前行起的每一行,用下一行数据覆盖本行数据,至第(tot-1)行
jna d2q
lea si,[bp+44].nam
lea di,[bp].nam
mov cl,[di]
xor ch,ch
sub cx,1
add di,2
as1: mov byte ptr [di],' '
inc di
loop as1
lea di,[bp].nam
ass
lea si,[bp+44].num
lea di,[bp].num
mov cl,[di]
xor ch,ch
sub cx,1
add di,2
as2: mov byte ptr [di],' '
inc di
loop as2
lea di,[bp].num
ass
lea si,[bp+44].asm
lea di,[bp].asm
mov cl,[di]
xor ch,ch
sub cx,1
add di,2
as3: mov byte ptr [di],' '
inc di
loop as3
lea di,[bp].asm
ass
lea si,[bp+44].ct
lea di,[bp].ct
mov cl,[di]
xor ch,ch
sub cx,1
add di,2
as4: mov byte ptr [di],' '
inc di
loop as4
lea di,[bp].ct
ass
lea si,[bp+44].os
lea di,[bp].os
mov cl,[di]
xor ch,ch
sub cx,1
add di,2
as5: mov byte ptr [di],' '
inc di
loop as5
lea di,[bp].os
ass
lea si,[bp+44].total
lea di,[bp].total
mov cl,3
xor ch,ch
as6: mov byte ptr [di],' '
inc di
loop as6
lea di,[bp].total
ast
lea si,tota ;对总分数组也执行同样的覆盖操作
add si,dx
add si,dx
mov di,si
add si,2
mov ax,[si]
mov [di],ax
inc dl
add bp,44
jmp lopd2
d2q: lea si,tota ;对总分数组的第tot项数据置0
add si,dx
add si,dx
mov [si],0
dec tot ;条目总数自减
ret
d2 endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -