在以BUF为首址的字节数据存储区中,存放着5个学生的课程成绩表(百分制),每个学生的相关信息包括:姓名(占6个字节,都以 0DH 为结束标记),语文成绩(1个字节),数学成绩(1个字节),英语成绩(1个字节),平均成绩(1个字节)。
例如:
BUF DB ‘iceyp’,0DH,100,90,80,? ; 请用自己的姓名拼音代替,分数自定
DB ‘zhang’,0DH,100,85,80,?
DB ‘lishi’,0DH,80,100,70,?
DB ‘wangw’,0DH,85,90,100,?
DB ‘xueyy’,0DH,60,55,40,?
提示并输入学生姓名
(1)使用9号DOS系统功能调用,提示用户输入学生姓名。
(2)使用10号DOS系统功能调用,输入学生姓名。输入的姓名字符串放在以in_name为首址的存储区中。
以学生姓名查询有无该学生
(1)采用子程序,实现两个串的比较
仿照 strcmp 函数,采用堆栈传递两个待比较串的首地址,(子程序从堆栈中获取两个串的首地址,两个串的结束标记是 0DH, 但两个串的长度可以不等),返回值在 AX 中。若 (AX)=1,表示两个串相同,(AX)=0, 表示不同。
注意:子程序只实现两个串的比较,并不是与学生信息表中的姓名逐一比较。应该使用循环程序结构,通过多次调用该子程序,实现逐一比较。
(2)若未找到,就提示用户该学生不存在;
(3)若找到,则提示该学生存在,并转功能三。
计算并显示查找到的学生的语文、数学、英语和平均成绩
(1) 使用算数运算相关指令计算并保存该学生的平均成绩。
平均成绩计算公式:(A+B+C)/3,要求避免溢出(解决中间三个数相加后大于255的情况)。
(2) 采用子程序,实现一个数字的显示。
入口参数:AL, 存放待显示的数据; (例 (AL)=64H , 在屏幕上显示 100 )
出口参数:无
通过多次调用该子程序,实现多个分数的显示。
主要要解决3个问题:
-
提示并输入学生姓名
-
以学生姓名查询有无该学生
-
计算所有学生的平均成绩
2.存储单元分配
DS:数据段寄存器
SI:存放BUF段各行的首地址
BP:存放缓冲区基址。
AL:存放平均成绩
AH:存放返回值
AX,DX,SI:临时寄存器
.386
STACK SEGMENT USE16 STACK
DB 200 DUP(0)
STACK ENDS
DATA SEGMENT USE16
INPUT DB 'PLEASE INPUT YOUR NAME:$'
FAIL DB 'NOT EXIST!$'
SUC DB 'EXIST!$'
IN_NAME DB 6
DB ?
DB 6 DUP(0)
BUF1 DB 'iceyp',0DH,100,90,80, ?
DB 'zhang',0DH,100,85,80, ?
DB 'lishi', 0DH,80,100,70, ?
DB 'wangw', 0DH,85,90,100, ?
DB 'xueyy',0DH,60,55,40, ?
CRLF DB 0DH,0AH,'$'
DATA ENDS
CODE SEGMENT USE16
ASSUME DS:DATA,SS:STACK,CS:CODE
START:
MOV AX, DATA
MOV DS, AX
MOV CH,5
LEA DX, OFFSET INPUT
MOV AH, 9
INT 21H /输出提示语句
LEA DX, IN_NAME
MOV AH,10
INT 21H /输入待查询的姓名
LEA SI,BUF1
LEA DI,IN_NAME
CALL COMP
COMP PROC
A1: PUSH SI /将SI压栈保存
CMP CH,0
JE END1
MOV CL,5
A2: MOV BL,[SI]
CMP BL,[DI+2] /比较字 符是否相等
JNE S
INC SI
INC DI
DEC CL
JNZ A2 /跳至A2
MOV AX,1
JMP END1
S:
DEC CH
MOV AX,0
POP SI
ADD SI,10
JMP A1
END1:
POP SI /将SI出栈
COMP ENDP
CMP AX,1
JE E
LEA DX, OFFSET CRLF
MOV AH, 9
INT 21H
LEA DX, OFFSET FAIL
MOV AH, 9
INT 21H
JMP ENDA
E:
LEA DX, OFFSET CRLF
MOV AH, 9
INT 21H
LEA DX, OFFSET SUC
MOV AH, 9
INT 21H
CALL AVER /进入计算平均值和输出的子程序
AVER PROC
PUSH DX
PUSH CX
MOV AX,0
MOV DX,0
MOV CX,0
MOV AL,[SI+6]
PUSH BYTE PTR 4
PUSH AX
CALL PADIX /输出第一个数字
MOV [SI+6],AL
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV AX,0
MOV AL,[SI+7]
PUSH BYTE PTR 4
PUSH AX
CALL PADIX
MOV [SI+7],AL
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV AX,0
MOV AL,[SI+8]
PUSH BYTE PTR 4
PUSH AX
CALL PADIX
MOV [SI+8],AL
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV AX,0
MOV AL,[SI+6]
ADD AL,[SI+7]
MOV CL,[SI+8]
ADD AX,CX
MOV DL,3
DIV DL /计算平均数值
MOV [SI+9],AL
MOV AL,[SI+9]
PUSH BYTE PTR 4
PUSH AX
CALL PADIX
JMP ENDA
AVER ENDP
PADIX PROC
PUSH AX
PUSH BX
PUSH CX
AND AH,0
MOV BL,100
DIV BL
MOV CL,AH
ADD AL,30H
MOV DL,AL
MOV AH,2
INT 21H
MOV AL,CL
MOV BL,10
AND AH,0
DIV BL
ADD AL,30H
MOV CL,AH
MOV DL,AL
MOV AH,2H
INT 21H
MOV AL,CL
ADD AL,30H
MOV DL,AL
MOV AH,2
INT 21H
POPCX
POP BX
POP AX
RET 4
PADIX ENDP
ENDA:
MOV AH,4CH
INT 21H
CODE ENDS
END START
1、环境条件:P3 1GHz,256M内存;WINDOWS 2000命令行窗口;EDIT.EXE 2.0;MASM.EXE 6.0; LINK.EXE 5.2; TD.EXE 5.0。
2、汇编源程序时,汇编程序没有报错。
图3.3
3、连接过程没有发生异常。
4、执行之后在新的一行上显示了字符串INPUT THE NAME
5、输入iceyp之后在冒号后显示EXIST 100 090 080 090
图3.4
6、程序退出到命令行提示符。
7、用TD调入7.exe后
(1)单步调试两条程序,显示数据段DS,可以观察到成绩在数据段中的显示
图3.5
(2)单步调试程序f2设置断点观察执行情况
(3)最后的运行结果为:
图3.6
8,查找姓名的子程序的入口参数为BP,BX,出口参数为AX,求平均成绩的子程序入口参数为BUF[BX],出口参数为AL,显示成绩的子程序的入口参数为AL,出口参数无。