##实现成绩输出显示的子程序
本篇来实现成绩输出显示功能
输出要用到之前的录入程序
所以直接在上次写好的文件里面写就行
1.我们把这个子程序放在function4里面写
先把fouth里面的代码改了
先执行清屏,
然后call function4
调用结束
回到主菜单
fourth:
mov ah,0
mov al,3
int 10h;BIOS中断功能 ah=0可以快速清屏,
call function4
jmp main;010f
然后把function4里面之前测试用的的清屏代码删掉
写我们要写的程序
function4 proc
mov ah,0
mov al,3
int 10h
ret
function4 endp
上面的代码删除
2.实现屏幕显示
我们用INT 21H 的02H功能
文档如下
我们用02H功能一个字符一个字符的显示
为什么这里不用09H呢
因为我们的内存中存储姓名和成绩的时候结尾没有$符号
所以如果用显示字符串的功能还要修改前面的代码
干脆直接用显示字符了
3.具体实现
来看具体代码吧
都写了注释
MOV SI,12h ;SI指向内存第二行第三个位置就是第一个人姓名的第一个字符
push SI; SI入栈 方便下面 换下一行显示
output:
mov DL,[SI];SI的值给DL
cmp DL,0h;如果是空白说明数据显示完了 跳到back
je back
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
add SI,01h; 让SI加01H,指向下一个字符
MOV DL,[SI];
cmp DL,0dh; 碰到0d就是“回车”说明这一行结束
je nextrow;跳到下一行
jmp output;上面没跳就跳回output 继续显示下一个字符
nextrow:
MOV DL,0DH;CR
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,0AH;LF
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
XOR ax,ax;清空ax dx
XOR dx,dx
pop SI;SI出栈 直接加10H 就指向下一行了
add SI,10H
push SI;进入output之前再让SI入栈
jmp output;循环output显示字符
back:;显示完毕跳转到这里
pop SI;栈里面清空 出栈SI
XOR AX,AX;清空寄存器
XOR DX,DX
XOR SI,SI
ret
ok这样就结束了
可是这样会导致
看不到显示结果
立刻就返回主菜单了
需要改进
4.代码改进
再ret之前我们加入功能
实现敲回车才返回菜单
back:
pop SI
XOR AX,AX
XOR DX,DX
XOR SI,SI
MOV AH,09H;显示字符串
LEA DX,mainmenu;取段内偏移地址
INT 21H;调用系统dos中断
Tenter:
MOV AH,01H;键盘输入 存入al
INT 21h
cmp al,0dh
jne Tenter
ret
这里的mainmenu 在数据段中是一段话
用INT 21H的01H功能
读取键盘的输入
如果是0D(就是回车)
返回主菜单
否则一直循环等待键盘输入回车
mainmenu DB 'type the enter to returm main menu $'
提示用户敲回车返回主菜单
运行一下看看结果
先录入2个人的成绩
输出显示
完
敲击回车才会返回菜单
完美
至此,
录入和输出功能的完整代码如下:
stack segment para stack 'stack'
db 256 dup(0)
stack ends
disp macro x,length,color
mov ax,1301h
mov bx,color
mov cx,length
mov dh,yy
mov dl,x
mov bp,addr
int 10h
endm
data segment
NUM DB 14,0,14 dup(?)
BUF1 DB 10 dup(2 dup(14,0,14 dup(?)))
INPUT DB 'welecome and please input the number of students N:$'
INPUTNAME DB 'please input the name with student NO.$'
INPUTSCORE DB 'please input the score with student NO.$'
mainmenu DB 'type the enter to returm main menu $'
N DB '0'
l0 db ' MENU '
l1 db '====================='
l2 db '| score-recording ';录入
l3 db '| score-update ';修改
l4 db '| score-sort ';排序
l5 db '| score-output ';输出
l6 db '| RETURN '
l7 db '====================='
LL EQU $-l7
XX equ (80-ll)/2
yy db ?
nn dw 1
tab dw ?,l2,l3,l4,l5,l6
addr dw ?
data ends
code segment
assume cs:code,ds:data,es:data
beg:
mov ax,data
mov ds,ax
mov es,ax
main:
mov ax,3
int 10h
mov yy,8
mov addr,offset l0
last2: disp xx,ll,0fh
add addr,ll
inc yy
cmp yy,16
jl last2
mov nn,1
call compute
disp xx+3,ll-6,51h
scan: mov ah,1
int 16h
jz scan
mov ah,0
int 16h
cmp ah,80
je down
cmp ah,72
je up
cmp al,0dh;006e
je select
jmp scan
down: cmp nn,5
je scan
call compute
disp xx+3,ll-6,0fh
inc nn
call compute
disp xx+3,ll-6,51h
jmp scan
up: cmp nn,1
je scan
call compute
disp xx+3,ll-6,0fh
dec nn;00d0
call compute
disp xx+3,ll-6,51h
jmp scan
select:
mov al,byte ptr nn
cmp al,1
je first
cmp al,2
je second
cmp al,3
je third
cmp al,4
je fourth
cmp al,5
je exit
first:
mov ah,0
mov al,3
int 10h;BIOS中断3号功能 这个ah=0h可以快速清屏,demo用的就是这个
call function1
jmp main;010f
second:
call function2
mov ah,4ch
int 21h
third:
call function3
mov ah,4ch
int 21h
fourth:
mov ah,0
mov al,3
int 10h;BIOS中断3号功能 这个ah=0h可以快速清屏,demo用的就是这个
call function4
jmp main;010f
exit:
mov ah,4ch
int 21h
function1 proc
MOV AH,09H;显示字符串
LEA DX,INPUT;取段内偏移地址
INT 21H;调用系统dos中断
MOV AH,0AH;键盘输入到缓冲区
LEA DX,NUM;取段内偏移地址
INT 21H;调用系统dos中断
MOV DL,0DH;CR
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,0AH;LF
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV SI,2
MOV al,NUM[SI];把输入的数存入al
SUB al,30H;ASCII数字变成纯数字
MOV ah,0;高位清零
MOV CX,AX;循环次数给CX
LEA DX,BUF1;上面的中断DX寄存器的值被修改了 这句必须加
push DX;dx入栈 存起来
LLLL1:
INC N
MOV AH,09H;显示字符串
LEA DX,INPUTNAME;取段内偏移地址
INT 21H;调用系统dos中断
MOV DL,N;传送字符
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,':';传送字符
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
pop DX;dx出栈
MOV AH,0AH;键盘输入到缓冲区
INT 21H;调用系统dos中断
ADD DX,10h;dx加10h就是加16,指向内存里面的下一行
push DX;dx入栈
MOV DL,0DH;CR
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,0AH;LF
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV AH,09H;显示字符串
LEA DX,INPUTSCORE;取段内偏移地址
INT 21H;调用系统dos中断
MOV DL,N;传送字符
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,':';传送字符
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
pop DX;dx出栈
MOV AH,0AH;键盘输入到缓冲区
INT 21H;调用系统dos中断
ADD DX,10h
push DX
MOV DL,0DH;CR
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,0AH;LF
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
LOOP LLLL1
pop DX;最后一定要出栈
ret
function1 endp
function2 proc
mov ah,0
mov al,3
int 10h
ret
function2 endp
function3 proc
mov ah,0
mov al,3
int 10h
ret
function3 endp
function4 proc
MOV SI,12h
push SI
output:
mov dl,[SI]
cmp dl,0h;开头是空白说明数据显示完了
je back
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
add SI,01h
MOV DL,[SI];
cmp DL,0dh;碰到0d说明这一行结束
je nextrow
jmp output
nextrow:
MOV DL,0DH;CR
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
MOV DL,0AH;LF
MOV AH,2;显示一个字符
INT 21H;调用系统dos中断
XOR ax,ax
XOR dx,dx
pop SI
add SI,10H
push SI
jmp output
back:
pop SI
XOR AX,AX
XOR DX,DX
XOR SI,SI
MOV AH,09H;显示字符串
LEA DX,mainmenu;取段内偏移地址
INT 21H;调用系统dos中断
Tenter:
MOV AH,01H;键盘输入 存入al
INT 21h
cmp al,0dh
jne Tenter
ret
function4 endp
compute proc near
mov di,nn
add di,di
mov ax,tab[di]
add ax,3
mov addr,ax
mov al,byte ptr nn
add al,9
mov yy,al
ret
compute endp
code ends
end beg