微机原理多功能程序的设计Word文档格式.docx
《微机原理多功能程序的设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《微机原理多功能程序的设计Word文档格式.docx(49页珍藏版)》请在冰豆网上搜索。
![微机原理多功能程序的设计Word文档格式.docx](https://file1.bdocx.com/fileroot1/2023-1/6/e886a04d-02a0-40c0-a650-9d99f9cce09d/e886a04d-02a0-40c0-a650-9d99f9cce09d1.gif)
3.日期显示功能。
在屏幕上以yyyy-mm-dd的格式显示系统日期、并以一定时间间隔随机改变显示位置;
4.闰年判断功能。
提示输入闰年,对输入内容具有容错处理,计算是否闰年,然后输出结果;
5.代码转换功能。
实现不同数制的输入并转换成另一种数制输出,如将十进制数转换为其对应的二进制数、将二进制数转换为其对应的十进制数、将十进制数转换为其对应的十六进制数、将十六进制数转换为其对应的十进制数等。
选一种或多种转换实现;
6.音乐播放功能。
利用计算机中的8253控制扬声器发音来实现;
能选择多首乐曲中的一首演奏,乐曲自选;
定义14个键,对应低音区和中音的1—7,模仿电子琴能随意演奏乐曲;
实验步骤与内容
按如下顺序写:
1、主要设计思想;
时间显示模块:
通过BIOS功能调用读取当前日期年、月、日和系统时钟时、分、秒数据,再转化为相应数字字符的ASCII码存放于内存缓冲区,再调用BIOS功能显示内存缓冲区的内容,为显示停留一段时间,需要延时,时长为近似一秒。
如此过程反复、循环实现时间的显示。
为显示能改变位置的目的,需改变显示位置的参数,通过产生随机数0-59送横坐标,0-24送纵坐标来改变时间显示的位置
闰年的判断模块:
输入前将YEAR单元清零,通过DOSAH01H,INT21H功能从键盘输入年份字符,检查输入的是否为数字字符,如果不是则提示输入错误;
如果是,则将其ASCII码减30H转化为数字(对应的BCD码)暂存入NUM中,将YEAR中的数值乘以10再加上NUM,这样就完成一个字符的输入,重复读取字符直到遇到回车或数值位数达到4位,这样得到的包括年份的千位、百位、十位、个位,之后转化为数字的年份做被除数去除4、100、400判断是否为闰年或者平年,并调用DOS09号功能显示判断结果。
进制转换模块:
实现十进制转二进制、十六进制,二进制转十进制,十六进制转十进制。
十进制转二进制:
读入字符,判断是否为合法字符(0~9),将字符转BCD码,再以二进制形式存入DX中,继续读入字符,先将DX中的内容乘以10再加上新的字符的二进制值,直到回车符,读取完毕。
将DX中的内容送BX(显示字符串要用DX)将BX循环左移(根据循环左移指令ROLdst,1/CL的功能:
将dst中的二进制位向左移动1位或CL中指定的位数。
左移一位时操作数的最高位移出送到CF中同时送到最低位)如果CF为零则输出字符零如果CF为一则输出字符1,这样就完成了二进制的输出。
二进制转十进制:
DX清零(用以存放输入的二进制数),读入字符,判断是否为合法字符(0、1)不是则报错;
将字符转换为对应的BCD码,判断输入的是0还是1,如果是0则DX左移一位,如果是1则DX左移一位并加1,重复读入字符直到遇回车符。
将DX中的内容送BX,DX清零用于存放余数。
将BX除以10得余数送DL中,再加上30H得到对应的ASCII码存入PTR1开始的第SI个单元如此重复就可以将转换的十进制数存入PTR1中,再加PTR1的内容显示出来即可。
十进制转十六进制:
输入遇十进制转二进制一致,将对应的二进制存放在BX中,DL循环左移四位,把要输出的内容放在低4位的DL中,将高4位清零。
DL中的内容与10比较,小于10的数字不变将其加上30H转换为对应的ASCII码输出对应字符,大于10的将数值加07H调整使10~15的字符变为A~F,输出对应的字符即可。
重复上述输出即完成了转换。
十六进制转十进制:
DX清零(用以存放输入的十六进制数),读入字符判断是否为(0~9)是的话直接减30H转为对应的BCD码,如果是(A~F)则减37H转为对应的BCD码,对应的二进制存入DX中,如果再读入字符则DX算术左移4位(即DX乘以16)再加上对应的字符二进制。
将BX除以10得余数送DL中,再加上30H得到对应的ASCII码存入PTR2开始的第SI个单元如此重复就可以将转换的十进制数存入PTR2中,再加PTR2的内容显示出来即可。
2、模块划分
读取系统时间模块
产随机数模块
时间显示模块显示模块
延迟模块
清屏模块
闰年的判断模块转换模块
十进制转二进制模块
检查合法字符模块
转换模块
十进制转十六进制模块
进制转换模块
二进制转十进制模块
检查合法字符模块
十六进制转十进制模块
3、程序源代码及注释;
见ASM文件,ASM文件名为学号太长了不能直接编译连接
程序的流程框图:
所有使用的DOS/BIOS功能调用:
从键盘读入字符
调试过程
开始时读取系统当前时间后显示,显示出的时间是正确的,但是后面会出现‘....’如图
,有时候是一整屏。
解决方法
INT1AH;
读取当前时间;
出口参数:
CX=时/分;
DH=秒
MOVAL,CH;
显示时
CALLDISP
MOVAH,09H;
绿色
MOVBL,0AH
MOVBH,0
MOVCX,1
INT10H
需将CX置1,但是读取的系统时间时、分存放在CX中,时已经显示出来但是分未显示,所以显示分的时候重新读取一下系统时间。
要不会出现
这样的错误。
MOVAH,02
重新读取当前时间;
MOVAL,CL;
显示分
会出现一半在右边,一半在左边的现象
原因:
DOS窗口长79,宽24,而时间字符串长20故横坐标不应该超过59,纵坐标不该超过24,如果横坐标超过59就会出现上述情况,如果纵坐标超过24则在窗口范围内没有显示出时间。
十进制转换二进制时输入的不是数字字符也会运行
解决方法:
添加一个检查字符功能,如果输入的不是0~9、回车符就提示输入错误。
本来以为退格符可以作为合法字符输入但是结果不对(测试时输入1、1、DEL、1)
我的解释是:
输入时是一个字符一个字符读入,前面11是合法字符,而这里的退格符也作为合法字符就又累加上DEL所对应的数值,然后又读入合法字符1,故回显的数值为11,而结果是不正确的,所以把退格符也定义为非法字符。
输入过程中不允许修改之前输入的内容。
问题:
如果要修改的话该怎么实现?
实验结果记录以及与预期结果比较以及分析
记录每次实验结果以及分析情况
菜单:
选择1(时间显示功能:
随机改变显示位置(每秒改变一次))
按ESC回到菜单
选择2(判断闰年)
Y回到菜单
选择4(音乐)
任意键返回主菜单
选择Q(退出)
选择3(进制转换)
按ESC返回主菜单
选择1(十进制转二进制)
Y回到子菜单
选择2(十进制转十六进制)
选择3(二进制转十进制)
选择4(十六进制转十进制)
演示完毕!
!
总结以及心得体会
通过一周的课程设计,使我加深对课程理论知识的理解,对各指令的使用更加熟悉。
所要完成的功能我们用c语言基本上完成过了,但是用汇编语言的确有一定的难度,在数据定义一块中定义菜单的时候还是不知道怎么画出好看的边框,还有怎么让选项居中,我这里是用空格去调整的。
通过这样一周的汇编编程训练,使我对课本知识有一次较全面的复习。
设计中写的函数比较多,实现各个函数间的相互调用等都需要较高的总体把握能力,通过这样的训练,无形中提高了分析问题和解决问题的能力;
提高了调试程序的能力。
编程经验:
1、首先,程序必须模块化。
2、每个模块(子程序)执行一个功能。
每个模块只有一个出口。
3、为每个子程序配置一个容易识别的函数名。
4、经常备份代码。
很多时候代码改着改着就不能运行了,而且错误非常多,这时候你备份的代码就派上用场了。
5、接受一个事实,你并不是最牛的程序员。
所以,要向他们学习,不懂要问(前提是尽自己最大的努力去思考问题了)。
6、给予别人帮助。
你或许从未意识到...这样你会使很多人成长,并且在帮助他们的同时你也会学到很多东西,而且你也会感到很开心。
7、给代码加注释,不论是自己调试的时候容易看出问题,问别人问题的时候,别人能很快看懂你的代码,帮你解决问题
程序改进之处:
检查合法字符模块check函数,可以通过给变量赋值,通过判断变量值执行相应的检查操作,这样就不用每个检查都写成一个函数。
同理随机数的产生也可以这样实现。
指导老师评阅意见
指导老师:
年月日
填写内容时,可把表格扩大。
实验的源程序代码(要有注释)附在表后。
STACKSSEGMENTSTACK;
堆栈段
DW128DUP(?
);
注意这里只有128个字节
STACKSENDS
DATASSEGMENT;
数据段
;
请在这里定义您的数据
----------------------------------------------------------------------------------
定义菜单
----------------------------------------------------------------------------------
STR1DB'
|------------------------------------------------------------------------------|'
0DH,0AH
DB'
|*1.SHIJIAN|'
|*2.RUNNIAN|'
|*3.JINZHI|'
|*4.YINYUE|'
|CHOOSE(1-4)TOPLAY!
QTOEXIT|'
|IFYOUAREPLAYING,YOUCANCHOOSEESCTORETURN!
|'
PLEASECHOOSE:
'
LENEQU$-STR1;
菜单长度
STR2DB'
CHANGE'
|*1.D->
B|'
|*2.D->
H|'
|*3.B->
D|'
|*4.H->
LEN0EQU$-STR2;
子菜单长度
-----------------------------------------------------------------------------------
定义其他数据
MESSAGE1DB'
PLEASEINPUTYOURYEAR:
LEN1EQU$-MESSAGE1
MESSAGE2DB'
THEYEARYOUENTERISALEAPYEAR!
LEN2EQU$-MESSAGE2
MESSAGE3DB'
THEYEARYOUENTERISNOTALEAPYEAR!
LEN3EQU$-MESSAGE3
MAINBDB'
DOYOUWANTTORETURNMAINMENU(Y/N):
LENBDW$-MAINB
ERRORDB'
ERROR:
PLEASEINPUTINTEGER!
LENERROREQU$-ERROR
MESSAGE4DB'
(DtoB)PLEASEINPUTTHENUMBERYOUWANTTOTRANSFORM:
LEN4EQU$-MESSAGE4
MESSAGE5DB'
(DtoH)PLEASEINPUTTHENUMBERYOUWANTTOTRANSFORM:
LEN5EQU$-MESSAGE5
MESSAGE6DB'
(BtoD)PLEASEINPUTTHENUMBERYOUWANTTOTRANSFORM:
LEN6EQU$-MESSAGE6
MESSAGE7DB'
(HtoD)PLEASEINPUTTHENUMBERYOUWANTTOTRANSFORM:
LEN7EQU$-MESSAGE7
STR3DB'
SORRY,THEREISNOMUSICCANBEPLAYEDHEAR!
PRESSANYKEYTORETURNTOMAINMENU......'
LEN8EQU$-STR3
YEARDW0
NUMDB0
TENDB0
HANDB0
THDB0
PROMPT_TWODB0AH,0DH,0AH,0DH,0AH,0DH,'
Thebinary:
$'
PROMPT_THRDB0AH,0DH,0AH,0DH,0AH,0DH,'
Thedecimal:
PROMPT_FORDB0AH,0DH,0AH,0DH,0AH,0DH,'
Theheximal:
STRINGDB?
0DH,0AH,'
$'
;
进制转化用
PTR1DB5DUP(?
PTR2DB5DUP(?
DATASENDS
CODESSEGMENT;
代码段
ASSUMECS:
CODES,DS:
DATAS,ES:
DATAS
START:
MOVAX,DATAS;
初始化
MOVDS,AX
菜单显示模块
RETURNM:
MOVES,AX
MOVAL,3
MOVAH,0;
设置80×
25彩色文本方式
MOVBP,SEGSTR1
MOVES,BP
MOVBP,OFFSETSTR1;
bp指向字符串首地址
MOVCX,LEN;
字符串长度给cx
MOVDX,0;
设置显示的起始位置
MOVBL,0AH;
黑底底绿字
MOVAL,1;
设置显示方式
MOVAH,13H;
显示字符串
MOVAH,3;
读取当前光标
选择操作
INPUT:
MOVAH,02H;
置光标位置
MOVDH,16
MOVDL,15
MOVAH,1;
输入菜单选择
INT21H
CMPAL,'
1'
选择1显示时间
JNZCHOOSE2
TT:
CALLTIME
MOVAH,01H;
检测键盘是否有输入
INT16H
CMPAL,1BH;
如果是ESC则返回主菜单
JZRETURNM
JMPTT
CHOOSE2:
2'
选择2判断闰年
JNZCHOOSE3
CALLLEAP
JMPINPUT
CHOOSE3:
3'
选择3进制转换
JNZCHOOSE4
CALLCHANGE
CHOOSE4:
4'
选择4音乐播放
JNZCHOOSEQ
CALLMUSIC
CHOOSEQ:
Q'
JZQUIT
QUIT:
MOVAX,4C00H;
退出程序
时间显示函数
TIMEPROC
PUSHAX
PUSHBX
PUSHCX
PUSHDX
MOVAH,00H;
置显示方式
MOVAL,03H
BEGAIN:
设置时间显示的位置
CALLRAND1
MOVDL,BL
CALLRAND2
MOVDH,BL
CALLTIMES
CALLDLY
CALLCLEAR
POPDX
POPCX
POPBX
POPAX
RET
TIMEENDP
-------------------------------------------------------------------------------
产生随机数送dl
--------------------------------------------------------------------------------
RAND1PROC
STI
读时钟计数器值
INT1AH
MOVAX,DX;
清高6位
ANDAH,3
MOVDL,60;
除60,产生0~59余数
DIVDL
MOVBL,AH;
余数存BX,作随机数
RAND1ENDP
----------------------------------------------------------------------------
产生随机数送dh
RAND2PROC
MOVAH,0;
INT1AH
MOVDL,25;
除24,产生0~24余数
RAND2ENDP
获取时间并完成显示函数
TIMESPROC
MOVAH,04
读取日期;
CX保存年,DX保存月/日
显示年
MOVAL,CL
MOVAH,0EH;
显示字符
MOVAL,'
-'
字符
MOVAL,DH;
显示月
MOVAL,D