汇编课程设计报告_第1页
汇编课程设计报告_第2页
汇编课程设计报告_第3页
汇编课程设计报告_第4页
汇编课程设计报告_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

万年历显示程序(《微机接口与汇编语言》)一、课题内容和要求题目描述:用汇编语言编写一个有简单界面显示的日历,要求输入年月日后,将该月的完整日历显示出来,包括星期几,且每月的星期六,日用不同颜色来表示。并且要求显示输入的日期。基本要求:(1)设计一个简单的接受键盘输入年月日信息的界面;(2)输入年月日后,将该月的完整日历显示出来,包括星期几,且每月的六,日。(3)实物演示时要求讲出程序原理和设计思想;(4)程序运行良好、界面清晰。提高要求:(1)界面色彩鲜明、友好,能够突出显示主题;(2)用不同的色彩明显表示出输入的日期;(3)错误输入要有提示及处理,结果显示清晰、合理。二、需求和思路分析 本课题要求设计一个显示万年历的程序,即要输入年月日后,将这个月的完整日历显示出来,包括这个月的每一天是星期几也要显示。公历每年有12个月,其中1、3、5、7、8、10、12月为大月,每月31天;4、6、9、11月为小月,每月30天。公历有闰年平年之分,若某年是闰年,则该年2月有29天,全年有366天;若某年是平年,则该年2月有28天。那么首先要做的就是完成通过键盘输入得到要显示的年月日,能够将年月日储存起来同时将输入的日期显示出来这个功能。在这里可以调用INT21H的0AH的功能将键入的一串字符送入用户程序的缓冲区,0AH功能要求键入的字符串必须以“回车”做为结束标志,换句话说,按下回车键后,本次功能调用结束。由于题目的要求错误输入要有提示及处理,所以也要考虑到所输入的年月日是否有符合日常逻辑,如果输入不正确,要显示出错误输入信息,并且提示重新输入年月日。本课题的重点的地方和难点的地方就是怎么将输入的日期的当月的完整日历给显示出来。那么就得在屏幕上先显示出星期一到星期日,在设计时将SUN…SAT在屏幕上显示出来,然后在下面依次显示完这个月的所有天数,而且要正确显示。在显示每个月的第一天的时候,首先要能够确定第一天是星期几。这样才能够正确的向下显示,并且显示这个月的最后一天不能够超出这个月的最大天数,在这里也就要考虑到各个月不同天数的情况,尤其是二月,闰年的二月有29天。在确定输入的那个月的第一天是星期几可以通过蔡勒公式求得,计算某一天是星期几,如下:W=[C/4]-2C+y+[y/4]+[13*(M+1)/5]+d–1,C是世纪数减1,y是年份后两位,M是月份,d是日数,计算出来的结果模取7。求得这个月的第一天是星期几后,会发现如果是星期一的话,最后算得的W的值为1,依次类推,星期日的W值为0,那么可以根据W值来确定要显示的行和列,最后限定一下要显示的这个月的最后一天,那么日历就可以正确的显示出来了。在用蔡勒公式计算的时候要注意1月和2月按上一年的13月和14月来算,这时C和y均按上一年取值。日历的显示也要注意光标的定位。设置星期六、日两列的字体为红色,打印出当前显示的是哪一年的哪一个月,打印出MON,TUR等字样,以标注哪天是星期几。根据月的大小进行循环的输出日期,在此过程中,要注意一位数与两位数对格式的影响,最后显示出来的界面要清洁。三、概要设计1.程序系统整体流程图:2.程序系统每个子程序的流程图(1)二进制转十进制子程序(2)判断闰年子程序(3)求输入的日期对应月的第一天是星期几四、详细设计1、输入年月日模块 本课题要求输入年月日就显示该月的日历,首先要做的是通过键盘来输入日期,在程序中使用INT21H的0AH的功能调用,它的功能是等待键入一串字符送入用户程序的数据缓冲区。0AH功能要求键入的字符串以“回车”做为结束标志,按下回车以后,本次功能调用结束,光标返回当前行始格。“回车”符留在缓冲区当中。对缓冲区的格式有如下要求,缓冲区要设置在程序数据段,调用前,缓冲区的首址偏移量应赋给DX寄存器。缓冲区首单元应预置“允许接收的字符个数”(包括回车键在内)。用户键入回车之后,由0AH功能把实际键入的字符个数(不包括回车键)写入STR1+1单元。键入的字符串从STR1+2单元开始依次存放。因此缓冲区的容量要不小于键入的键入的串的长度(包括回车键)+2。在程序中这么定义的:STR1DB 9 DB ? DB 9DUP(?)比如要输入20090327,这样只能输入像这种格式的8个字符。这样输入就完成了,但是由于输入的是年月日,也要判断其是否符合现实。也就要对输入的年月日进行处理,如果输入不正确就提示出错,并且重新输入。判断输入的是否正确有以下几个方面要考虑,首先输入的月只能在01-12里面的情况,日的最小天数要不小于1,最大不能超过刚才输入的月的最大天数。在程序里,我是通过这样的方法实现的,我把12个月的天数定义为BUF1DB31,?,31,30,31,30,31,31,30,31,30,31,其中?就是2月的天数,由于不知道输入的年是否是闰年,所以2月的最大天数在这里还未知。下面要做的就是首先判断输入的年是否是闰年,程序中通过CALLPR调用判断平年还是闰年的程序。关于通过什么算法来判断是否闰年的这里就不再详细的介绍了,算法的流程图已经在上面给出了。通过算法判断得出输入的年是否是闰年,如果是闰年那么就将29存到刚才定义的BUF1里面,如是平年就将28存到BUF1里。这样通过输入的月就可以知道每个月的最大天数了。比如输入的是1月,那么就调用BUF1里面第一个数据就知道1月的最大天数31天了。一个输入年月日的模块也就完成了,也能够判断输入是否正确。2、显示日历模块 课题中对于显示也作了要求:日历的显示。注意光标的定位。设置星期六、日两列的字体为红色,打印出当前显示的是哪一年的哪一个月,打印出MON,TUR等字样,以标注哪天是星期几。根据月的大小进行循环的输出日期,在此过程中,要注意一位数与两位数对格式的影响。另外,打印到星期天要输出换行。要打印出MON,TUR等字样,以标注哪天是星期几。首先定义一个数据缓冲区WEEKDB"SUNMONTUEWEDTHUFRISAT$"然后在后面直接用显示功能,使其在屏幕中显示出来。下面做的就是要输出输入的月的所有天数,这里关键先要判断这个月的第一天是星期几,算法在上面流程图中也给出了。通过算法得出月的第一天是星期几,然后往下依次输出其最大天数从上面的BUF1中获取。对于题中给的要求,设置星期六、日两列的字体为红色。这个只需在显示日历的时候,判断要显示的是否是第一列和最后一列,如果是就运用BIOS的INT10H的06H功能就能将其颜色设置成红色。其入口参数AL=上卷行数;AL=0:整个窗口空白,BH=卷入行属性,CH:CL=左上角行号:列号,DH:DL=右下角行号:列号。对于上面的输入日期的颜色以及程序运行的背景颜色也都是通过这种方法实现的。3、源程序代码:DATASSEGMENTA1DB"=====================================$"A2DB"*******Calendar********$"A3DB"designer:Wubinghui$"A4DB"Pleaseinputthedate:$"A5DB"Pleaseinputthedatelike:20090101$"STR1DB9 DB? DB9DUP(?)A6 DW0A7DB0A8 DB"Date:$" B DW?C1DW0C2DB0GDB0N DB?P DW?YDB?WEEKDB"SUNMONTUEWEDTHUFRISAT$"YEAR DW?MONTHDW?DAYDW?WRONGDB"Thedateyouinputiswrong!Pleasetryagain$"ROW DB1BUF1 DB31,?,31,30,31,30,31,31,30,31,30,31BUF2 DB1,2,3,4,5,6,7,8,9,10,11,12BUF3 DB'1',0AH,0DH,'$' DB'2',0AH,0DH,'$' DB'3',0AH,0DH,'$' DB'4',0AH,0DH,'$' DB'5',0AH,0DH,'$' DB'6',0AH,0DH,'$' DB'7',0AH,0DH,'$' DB'8',0AH,0DH,'$' DB'9',0AH,0DH,'$' DB'10',0AH,0DH,'$' DB'11',0AH,0DH,'$' DB'12',0AH,0DH,'$' DB'13',0AH,0DH,'$' DB'14',0AH,0DH,'$' DB'15',0AH,0DH,'$' DB'16',0AH,0DH,'$' DB'17',0AH,0DH,'$' DB'18',0AH,0DH,'$' DB'19',0AH,0DH,'$' DB'20',0AH,0DH,'$' DB'21',0AH,0DH,'$' DB'22',0AH,0DH,'$' DB'23',0AH,0DH,'$' DB'24',0AH,0DH,'$' DB'25',0AH,0DH,'$' DB'26',0AH,0DH,'$' DB'27',0AH,0DH,'$' DB'28',0AH,0DH,'$' DB'29',0AH,0DH,'$' DB'30',0AH,0DH,'$' DB'31',0AH,0DH,'$'DATASENDSSTACKSSEGMENTSTACKSENDSCODESSEGMENTASSUMECS:CODES,DS:DATAS,SS:STACKSSTART: MOVAX,DATAS MOVDS,AX MOVAH,0 ;设置显示方式 MOVAL,3 ;80*25彩色文本方式 INT10H MOVAH,6 MOVAL,0 MOVCH,0 MOVCL,0 ;清整个屏幕 MOVDH,80 MOVDL,80 MOVBH,10110000B ;前四位定义背景色,后四位定义前景色 INT10H MOVDH,ROWMOVDL,2CALLGBIAOLEADX,A1CALLNINEADDROW,2MOVDH,ROWMOVDL,1CALLGBIAOLEADX,A2CALLNINEADDROW,2MOVDH,ROWMOVDL,8CALLGBIAOLEADX,A3CALLNINEADDROW,2MOVDH,ROWMOVDL,1CALLGBIAOLEADX,A5CALLNINEADDROW,2REINPUT:MOVAH,6 ;输入日期显示蓝色 MOVAL,0 MOVCH,ROW MOVCL,23 MOVDH,ROW MOVDL,30 MOVBH,10110001B INT10HMOVDH,ROWMOVDL,1CALLGBIAOLEADX,A4CALLNINEMOVDH,ROWMOVDL,23CALLGBIAO LEADX,STR1;输入日期,保存在缓冲区STR1中MOVAH,10INT21HADDROW,2LEADI,STR1+2;DI指向日期输入串的首地址MOVCX,4MOVAX,0P1: MOVBL,[DI] ;取字符送到BL SUBBL,30H ;字符减去30H,转化为真值 MOVBH,0 MOVP,10 MULP ADDAX,BX INCDI ;DI指向下一个字符 DECCX ;长度减一 JNZP1 MOVYEAR,AXCALLPR ;调用判断平年还是闰年的程序 JCL1 ;有进位,借位,跳转到L1,输出闰年,否则顺序执行,是平年 LEADI,BUF1MOV[DI+1],BYTEPTR28 ;平年把28送入BUF1中 JMPL2L1: LEADI,BUF1MOV[DI+1],BYTEPTR29 ;闰年把29送入BUF1中L2: LEADI,STR1+6MOVCL,2MOVAX,0P2: MOVBL,[DI] SUBBL,30H MOVBH,0 MOVP,10 MULP ADDAX,BX INCDI DECCX JNZP2 MOVMONTH,AX ;获得月份值 LEADI,STR1+8 MOVCL,2 MOVAX,0P3: MOVBL,[DI] SUBBL,30H MOVBH,0 MOVP,10 MULP ADDAX,BX INCDI DECCX JNZP3 MOVDAY,AX ;获得输入的日数 CMPMONTH,1 ;月份<1,报错 JCERROR CMPMONTH,13 ;月份>12,报错 JNCERROR CMPDAY,1 JCERROR CALLGETN ;显示日历,调用GETN子程序返回N的值,N为每月第一天是星期几 MOVDI,OFFSETBUF1 DECMONTH DECMONTH ADDDI,MONTH ;取出每个月的天数--->G MOVCL,[DI] MOVG,CL CMPBYTEPTRDAY,CL ;输入的天如果超过这个月的最大天数,报错 JAERROR MOVDH,ROW MOVDL,10 CALLGBIAO LEADX,A8 CALLNINE MOVDH,ROW MOVDL,16 CALLGBIAO LEADI,STR1+2MOVCL,8MOVAX,0DATE: MOVBL,[DI] MOVDL,BL MOVAH,2 INT21H INCDI DECCX JNZDATE ADDROW,1 MOVAH,6 MOVAL,0 MOVCH,ROW MOVCL,3 MOVDH,ROW MOVDL,0 MOVBH,10110100B INT10H ;SUNSAT设置红色 MOVAH,6 MOVAL,0 MOVCH,ROW MOVCL,30 MOVDH,ROW MOVDL,33 MOVBH,10110100B INT10H MOVDH,ROW MOVDL,0 CALLGBIAO LEADX,WEEK CALLNINE ;显示SUN*******************SAT INCROW MOVSI,OFFSETBUF3 MOVAL,5 MULN MOVB,AX CMPB,35;如果每个月一号是星期天,显示一号的行号减2 JCPOS SUBROW,1 POS:MOVDH,ROW ;每个月的一号的光标位置 MOVDL,BYTEPTRB CALLGBIAO MOVA7,31 CMPDL,A7 JBEPOS1 ;DL<31,跳转到POS1,否则行加1,列从0开始 ADDROW,1 ;两行日期间隔 MOVAX,0 MOVB,AX MOVAH,6 ;日历周末设置红色显示 MOVAL,0 MOVCH,ROW MOVCL,3 MOVDH,ROW MOVDL,0 MOVBH,10110100B INT10H JMPPOSPOS1: CMPDL,30;周六的日历显示红色JCNORED MOVAH,6 MOVAL,0 MOVCH,ROW MOVCL,30 MOVDH,ROW MOVDL,33 MOVBH,10110100B INT10HNORED: MOVDX,SI CALLNINE ;在当前光标位置显示数字 ADDSI,5 ADDB,5 ;两个日期的显示距离 DECG JNZPOS JMPEXIT ERROR:DECROW MOVDH,ROW MOVDL,1 CALLGBIAO LEADX,WRONG CALLNINE INCROW JMPREINPUT EXIT: MOVAH,4CH INT21HGBIAOPROCPUSHAXPUSHBXMOVAH,2 ;2号功能调用MOVBH,0INT10H;定光标POPBXPOPAXRETGBIAOENDPNINEPROCPUSHAXMOVAH,9 ;9号功能调用INT21HPOPAXRETNINEENDPPRPROC ;判断是平年还是闰年 PUSHAX PUSHBX PUSHCX PUSHDX MOVAX,YEAR MOVCX,AX MOVDX,0 MOVBX,4 DIVBX CMPDX,0 ;DX中为余数 JNZB1 MOVAX,CX MOVBX,100 DIVBX CMPDX,0 JNZB2 MOVAX,CX MOVBX,400 DIVBX CMPDX,0 JZB2B1: CLC ;CF=0 JMPB3B2: STC ;CF=1B3: POPDX POPCX POPBX POPAX RETPRENDPGETNPROC ;获得这个月的一号是星期几 PUSHAX PUSHBX PUSHCX PUSHDX MOVBL,100 MOVAX,YEAR DIVBL MOVC2,AL MOVY,AH MOVCL,2 MOVBL,C2 SHR BL,CL ;int(c/4) SHLC2,1 ;2*c SUBBL,C2 ADDBL,Y SHRY,CL ;int(y/4) ADDBL,Y ;int(c/4)-2*c+y+int(y/4) INCMONTH CMPMONTH,3 ;是一月,转移 JCJ1 ;是二月,转移 CMPMONTH,4 JCJ1 XORAH,AH MOVAX,MONTH MOVDX,13 MULDX MOVCX,5 DIVCX XCHGAX,BX CBW XCHGAX,BX ADDBX,AX ;int(c/4)-2*c+y+int(y/4)+int(13*(m+1)/5) MOVAX,BX MOVCL,7 IDIVCL CMPAH,0 JGSKIPADD ADDAH,7SKIPADD: MOVBL,AH MOVN,BL JMPJ3J1:MOVBL,100 MOVAX,YEAR DIVBL MOVC2,AL MOVY,AH CMPY,1 ;如果年份后两位是00,则前一年是99 JNCJ2 ADDY,100J2:SUBY,1 MOVCL,2 MOVBL,C2 SHR BL,CL SHLC2,1 SUBBL,C2 ADDBL,Y SHRY,CL ADDBL,Y ADDMONTH,12 XORAH,AH MOVAX,MONTH MOVDX,13 MULDX MOVCX,5 DIVCX XCHGAX,BX CBW XCHGAX,BX ADDBX,AX MOVAX,BX MOVCL,7 IDIVCL CMPAH,0 JGSKIPADD1 ADDAH,7SKIPADD1: MOVBL,AH MOVN,BL SUBMONTH,12J3: POPDX POPCX POPBX POPAX RETGETNENDPCODESENDSENDSTART五、测试数据及其结果分析输入模块测试:错误输入时见下图根据图所示,当输入的年月日不符合现实的情况时,程序报错,并提醒重新输入。正确输入时,显示日历正确输入时,按照课题的要求将这个月的日历显示出来了。六、调试过程中的问题 在实验的过程中,在设置将输入的年月日用蓝色表示时,将其中的一句代码MOVCX,4写成了MOVCL,4后发现程序运行出错,如下图:刚开始不知道是什么问题,后来再用编译软件,通过一步一步走的时候,观察寄存器里面的数据,如果按上面CL存4时,由于在前面用到CX寄存器,它里面的CH有值,执行MOVCL,4后,CX的值并不为4,影响了后面的计数作用。后来将CL改成CX发现,程序没有报错,而且正确的显示了日历。还有在正确输入时显示日历前有一行将输入的年月日显示出来,刚开始将这代码嵌在判断日是否满足要求的前面,导致在月输入错误时不显示DATE:的情况而日出现错误时将DATE:给显示出来了,发现这个问题后就将这部分代码写到了后面。刚开始设计算每个月的第一天是星期几,运用蔡勒公式没有考虑到1月和2月的情况,导致程序运行时其他的月准确,1月和2月出现错误,于是就在代码里面进行判断,如果输入的是1月和2月就按上一年的13月和14月进行计算,但上一年里面也要考

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论