大奖赛记分程序设计.docx
《大奖赛记分程序设计.docx》由会员分享,可在线阅读,更多相关《大奖赛记分程序设计.docx(17页珍藏版)》请在冰点文库上搜索。
![大奖赛记分程序设计.docx](https://file1.bingdoc.com/fileroot1/2023-5/23/3128b861-4ff7-468f-abc0-c0c60467a059/3128b861-4ff7-468f-abc0-c0c60467a0591.gif)
大奖赛记分程序设计
南京工程学院
课程设计报告书
课程名称微机原理及应用B
院(系、部、中心)自动化学院
专业
班级
姓名
学号
起止日期
指导教师
目录
一、设计题目…………………………………………
二、设计任务(要求)………………………………
三、总体方案…………………………………………
四、原理框图…………………………………………
五、系统模块详细设计与调试………………………
六、设计总结…………………………………………
七、参考文献…………………………………………
八、附件材料…………………………………………
一、设计题目
大奖赛记分程序设计
二、设计任务(要求)
1、设计要求
编制一个程序,实现选手成绩的平均分计算。
设有十个评委给参赛的选手评分,分数是从键盘上输入的十个十进制数(一位或两位)。
(1)把输入的十进制数转换成二进制数,并求出最大数和最小数;
(2)求出十个数的总和,减去最大数和最小数,求出平均值;
(3)将二进制的平均值转换成十进制,并在屏幕上显示十进制的结果。
2、界面要求
(1)首先显示器显示:
“PLEASEIUPUTTHE10SCORES!
”;
(2)输入成绩后屏幕上显示十个分数,以及最后的平均值;
(3)要求输入的分数以“Enter”键结束。
三、总体方案
1、利用DOS中断的09号功能,在屏幕上显示提示语句,要求输入十个分数。
MOVAH,09H
MOVDX,OFFSETBUF;BUF为存放十个分数的存储区首地址
INT21H
设置数据保存区,将转换后的二进制数存入其中。
2、将输入的十进制数转换为二进制数。
因为从键盘接收的数据是以ASCII码存放在数据缓冲区,并且两位数的十位和个位分别存放在两个地址单元,可先将其转换成BCD数,然后再利用除法ASCII码调整指令AAD将其转换成二进制数。
3、求十个数中的最大数和最小数。
假设第一个数是最大数,并送到MAX单元中,依次把余下的数与MAX单元中的数相比较,如大于MAX中的数,则把此数送到MAX单元中,否则取下一个数,最后MAX单元中即为最大数,同理可求出最小数。
4、计算十个数的总和再减去最大数和最小数,最后除以8,即求出平均数。
5、最后所得结果是二进制数,可先除以10,商就是十位,余数就是个位。
分别加上30H转换为ASCII码,利用DOS中断的02H功能可在屏幕上显示结果。
MOVAH,02H
INT21H;DL存放要显示的数的ASCII码
四、原理框图
主程序流程图如下:
五、系统模块详细设计与调试
(一)系统模块详细设计
1、模块一:
宏指令的定义与调用
在显示器提示信息后和输入数据后,都需要回车换行,在本程序中用一个宏指令CRLF来实现。
宏指令CRLF中又调用了另外一个宏指令DOSFUNC,这是一个带参数的宏指令。
宏指令需定义在程序的最前面。
宏定义:
DOSFUNCMACRONO;定义宏指令DOSFUNC
MOVAH,NO
INT21H
ENDM;宏DOSFUNC结束
CRLFMACRO;定义宏指令CRLF
MOVDL,0DH;回车
DOSFUNC2;2号功能调用――显示字符
MOVDL,0AH;换行
DOSFUNC2
ENDM;宏CRLF结束
CRLF宏指令用2号DOS功能调用(显示一个字符)显示回车符与换行符的方法来实现回车换行。
2号DOS功能在显示回车符与换行符时实际上只是把光标移到下一行的开始,而并非把0DH和0AH显示在屏幕上。
宏调用:
在程序中凡是需要进行回车换行的地方只要把CRLF当作一条无操作数指令直接插入该处即可。
在程序中若要使用DOSFUNC宏指令,需要在DOSFUNC宏指令后带上实参(功能调用的功能号)。
2、模块二:
数据段的定义
DATASEGMENT;定义数据段
MESSAGEDB‘PLASEINPUTTHE10SCORES!
’0DH,0AH,‘$’
;键盘缓冲区
NUMBERSDB10DUP(?
);键入的数据转换成二进制后放在此处
KBDB3;定义可接收最大字符数(包括回车键)
ACTLENDB?
;实际输入的字符数
BUFFERDB3DUP(?
);输入的字符放在此区域中
MAXDB?
;最大数
MINDB?
;最小数
DATAENDS;数据段结束
键盘缓冲区第一个字节存放它能保存的最大字符数,第二个字节存放实际输入的字符数(由0AH号功能负责填入),用户从键盘输入的字符串从第三个字节放起,用户以Enter键结束本次输入。
如果输入的字符数超过所定义的键盘缓冲区所能保存的最大字符数,0AH功能将拒绝接收多出的字符。
输入结束时的Enter键也作为一个字符(0DH)放入字符缓冲区,因此设置的缓冲区应比希望输入的字符数多一个字节。
在调用0AH号功能前需将键盘输入缓冲区的偏移地址放到DX寄存器中。
3、模块三:
代码段的定义
CODESEGMENT;定义代码段
ASSUMECS:
CODE,DS:
DATA,ES:
DATA
START:
MOVAH,00H
MOVAL,03H
INT10H(设置屏幕显示方式)
MOVAX,DATA
MOVDS,AX
MOVES,AX
LEADX,MESSAGE
DOSFUNC9;显示MESSAGE
;
(1)从键盘读入数据并转换成二进制数保存。
因为从键盘接收的数据是以ASCII码存放在数据缓冲区,并且两位数的十位和个位分别存放在两个地址单元。
对于一位数,可将其转换为BCD数,即为二进制数;两位数可先将其转换成BCD数,然后再利用除法ASCII码调整指令AAD将其转换成二进制数。
因此在转换数制前需判定输入的数的位数,然后跳入相应的程序段中完成ASCII码到二进制数的转换。
MOVCX,10
LEADI,NUMBERS;设置数据保存区指针
L1:
LEADX,KB
DOSFUNC0AH;从键盘读数据
CMPACTLEN,0
JZL1
CMPACTLEN,1
JNZL2
MOVAL,BUFFER;若只有一个数字
ANDAL,0FH;转换成二进制数
JMPL3
L2:
MOVAH,BUFFER;若有两个数字
MOVAL,BUFFER+1
ANDAX,0F0FH;转换成BCD数
AAD;转换成二进制数
L3:
STOSB;保存数据
CRLF
LOOPL1;直到10个数据都输入完
;
(2)求最大数和最小数。
假设第一个数是最大数,并送到MAX单元中,依次把余下的数与MAX单元中的数相比较,如大于MAX中的数,则把此数送到MAX单元中,否则取下一个数,最后MAX单元中即为最大数,同理可求出最小数。
L4:
MOVCX,9;比较次数
LEASI,NUMBERS;数据保存区首字的偏移地址
送至寄存器SI
MOVAL,[SI];取第一个数送AL
MOVMAX,AL;将第一个数送至MAX单元
MOVMIN,AL;将第一个数送至MIN单元
COMP:
INCSI
MOVAL,[SI];取下一个数
CMPAL,MAX;与MAX单元中的数比较
JLNEXT;若不大于MAX中
的数则跳到
NEXT继续执行
MOVMAX,AL;否则将其送到MAX单元中
JMPSHORTLOP
NEXT:
CMPAL,MIN
JGLOP;若不小于MIN中的数则跳
LOP继续执行
MOVMIN,AL;否则将其送至MIN单元中
LOP:
LOOPCOMP
;(3)计算十个数的总和再减去最大数和最小数,最后除以8,即求出
平均数。
LEASI,NUMBERS;数据保存区首字的偏移地址送
至寄存器SI
MOVCX,9
MOVAL,[SI];取第一个数
MOVAH,0;AH清零
L5:
INCSI
MOVDL,[SI];取下一个数
MOVDH,0;DH清零
ADCAX,DX;求和,并将结果送至AX
LOOPL5;求出十个数的总和
L6:
MOVBL,MAX;取最大数
MOVBH,0
SUBAX,BX;十个数的总和减去最大数
MOVBL,MIN;取最小数
MOVBH,0
SUBAX,BX;再减去最小数
MOVBL,8
DIVBL;求平均数
;(4)所得结果是二进制数,可先除以10,商就是十位,余数就是个位。
分别加上30H转换为ASCII码,利用DOS中断的02H功能可在屏幕上
显示结果。
MOVCL,AH;将求得平均数后的余数送至CL
ANDAX,0FFH;AH清零
MOVBL,10
DIVBL
MOVCH,AH;平均数的个位送至CH
MOVDL,AL;十位送至AL
ADDDL,30H;转换成ASCII码
MOVAH,02H
INT21H;显示十位
MOVDL,CH
ADDDL,30H
MOVAH,02H
INT21H;显示个位
MOVDL,2EH
MOVAH,02H
INT21H;显示小数点
MOVAL,CL;取余数
MOVBL,10
MULBL
MOVBL,8
ANDAX,0FFH
DIVBL
MOVDL,AL
ADDDL,30H;将余数转换为ASCII码
MOVAH,02H
INT21H;显示小数点后的数
MOVAH,4CH
INT21H;返回DOS
CODEENDS;代码段结束
ENDSTART;程序结束
(二)系统调试
源程序建立以后,要对其进行汇编。
汇编程序会指出源程序中的错误,这些错误要经过调试阶段才能纠正,从而得到正确的结果。
常用的调试程序为DEBUG程序,它通过单步、设置断点等方式提供了非常有效的调试手段。
将源程序经过汇编后得到没有语法错误的OBJ文件,然后用连接程序(LINK)把OBJ文件转换成可执行的EXE文件,在DOS环境下可直接运行该文件,但运行后系统提示除数溢出。
我在程序中找不到错误,只好用DEBUG调试。
只需退出EDIT环境,输入TDEBUG
加文件名之后回车,就可进入DEBUG程序环境,对源程序进行调试。
我根据系统提示,利用F8单步执行程序,观察每一步的结果。
当执行到数制转换那里时,我发现结果出现了问题,两位数转换之后还是正确的,但一位数就不对了,它的高八位居然是前面输入的两位数的高位,接下来输入的数转换后的结果也不正确。
原先数制转换部分程序如下:
CMPACTLEN,0
JZL1
CMPACTLEN,1
JNZL2
MOVAL,BUFFER;若只有一个数字
ANDAL,0FH;转换成二进制数
JMPL3
L2:
MOVAH,BUFFER;若有两个数字
MOVAL,BUFFER+1
ANDAX,0F0FH;转换成BCD数
AAD
L3:
MOV[SI],AX
INCSI
LOOP
由于SI是十六位存储器,执行INCSI每次只加一个字节,两位数在保存时就会出现问题,因为转换后的两位数要占两个字节,可以把两位数与一位数分开保存或采用串传送指令一位位保存。
L3段修改后修改后如下:
L3:
STOSB;保存数据
CRLF
LOOPL1;直到10个数据都输入完
把这个错误改正过来以后,后面的除数溢出问题也就迎刃而解了。
六、设计总结
七、参考文献
1、《微机原理实验与课程设计指导书》,陆红伟编,中国电力出版社,2006年
2、《8086微型计算机组成、原理及接口》,顾滨编,机械工业出版社,2001年
3、《微机原理及应用》,徐晨、陈继红、王春明、徐慧编,高等教育出版社,2004年
4、《微型计算机原理与接口技术题解及实验指导》,陈文革等编,清华大学出版社,2003年
5、《微型计算机原理及应用》,吕叔萍等编,哈尔滨工程大学出版社,2004年
6、《微型计算机技术及应用》,戴梅萼编,清华大学出版社,2005年
八、附件材料
程序清单如下:
DOSFUNCMACRONO;定义宏指令DOSFUNC
MOVAH,NO
INT21H
ENDM;宏DOSFUNC结束
CRLFMACRO;定义宏指令CRLF
MOVDL,0DH;回车
DOSFUNC2;2号功能调用――显示字符
MOVDL,0AH;换行
DOSFUNC2
ENDM;宏CRLF结束
DATASEGMENT;定义数据段
MESSAGEDB‘PLASEINPUTTHE10SCORES!
’0DH,0AH,‘$’
;键盘缓冲区
NUMBERSDB10DUP(?
);键入的数据转换成二进制后放在此处
KBDB3;定义可接收最大字符数(包括回车键)
ACTLENDB?
;实际输入的字符数
BUFFERDB3DUP(?
);输入的字符放在此区域中
MAXDB?
;最大数
MINDB?
;最小数
DATAENDS;数据段结束
CODESEGMENT;定义代码段
ASSUMECS:
CODE,DS:
DATA,ES:
DATA
START:
MOVAH,00H
MOVAL,03H
INT10H(设置屏幕显示方式)
MOVAX,DATA
MOVDS,AX
MOVES,AX
LEADX,MESSAGE
DOSFUNC9;显示MESSAGE
MOVCX,10
LEADI,NUMBERS;设置数据保存区指针
L1:
LEADX,KB
DOSFUNC0AH;从键盘读数据
CMPACTLEN,0
JZL1
CMPACTLEN,1
JNZL2
MOVAL,BUFFER;若只有一个数字
ANDAL,0FH;转换成二进制数
JMPL3
L2:
MOVAH,BUFFER;若有两个数字
MOVAL,BUFFER+1
ANDAX,0F0FH;转换成BCD数
AAD;转换成二进制数
L3:
STOSB;保存数据
CRLF
LOOPL1;直到10个数据都输入完
L4:
MOVCX,9;比较次数
LEASI,NUMBERS;数据保存区首字的偏移地址
送至寄存器SI
MOVAL,[SI];取第一个数送AL
MOVMAX,AL;将第一个数送至MAX单元
MOVMIN,AL;将第一个数送至MIN单元
COMP:
INCSI
MOVAL,[SI];取下一个数
CMPAL,MAX;与MAX单元中的数比较
JLNEXT;若不大于MAX中的数则跳到
NEXT继续执行
MOVMAX,AL;否则将其送到MAX单元中
JMPSHORTLOP
NEXT:
CMPAL,MIN
JGLOP;若不小于MIN中的数则跳
LOP继续执行
MOVMIN,AL;否则将其送至MIN单元中
LOP:
LOOPCOMP
LEASI,NUMBERS;数据保存区首字的偏移地址送
至寄存器SI
MOVCX,9
MOVAL,[SI];取第一个数
MOVAH,0;AH清零
L5:
INCSI
MOVDL,[SI];取下一个数
MOVDH,0;DH清零
ADCAX,DX;求和,并将结果送至AX
LOOPL5;求出十个数的总和
L6:
MOVBL,MAX;取最大数
MOVBH,0
SUBAX,BX;十个数的总和减去最大数
MOVBL,MIN;取最小数
MOVBH,0
SUBAX,BX;再减去最小数
MOVBL,8
DIVBL;求平均数
MOVCL,AH;将求得平均数后的余数送至CL
ANDAX,0FFH;AH清零
MOVBL,10
DIVBL
MOVCH,AH;平均数的个位送至CH
MOVDL,AL;十位送至AL
ADDDL,30H;转换成ASCII码
MOVAH,02H
INT21H;显示十位
MOVDL,CH
ADDDL,30H
MOVAH,02H
INT21H;显示个位
MOVDL,2EH
MOVAH,02H
INT21H;显示小数点
MOVAL,CL;取余数
MOVBL,10
MULBL
MOVBL,8
ANDAX,0FFH
DIVBL
MOVDL,AL
ADDDL,30H;将余数转换为ASCII码
MOVAH,02H
INT21H;显示小数点后的数
MOVAH,4CH
INT21H;返回DOS
CODEENDS;代码段结束
ENDSTART;程序结束