万年历的8086汇编实现

这是一个使用8086汇编语言编写的万年历程序,用户可以输入年份和月份,程序会显示相应的月历。程序通过键盘监听,允许用户通过上下左右键改变年份和月份,星期六和星期日以红色显示。程序包括主程序和打印模块,采用蔡勒公式计算特定日期的星期几。用户输入非法时,程序会提示重新输入,直至输入合法或按ESC退出。
摘要由CSDN通过智能技术生成
 
设计题目:
用汇编语言编写一个打印月历的程序,要求用户在开始输入年、月。以后可以通过按下上下键来改变年份;左右键来改变月份。且每月的星期六、日用红色显示出来。
程序思路:
程序分为两大模块:主程序和具体打印部分。主程序负责处理用户的年、月输入;监测键盘动作,并把得到的信息处理成相应的入口参数送给打印模块。打印模块接受主程序的调用,对给定的年、月,打印出相应的月历。并且,处理界面上的要求。
程序中用到的算法(计算某一天是星期几):
     蔡勒公式: W = [C/4] - 2C + y + [y/4] + [13 * (M+1) / 5] + d - 1
C是世纪数减一,y是年份后两位,M是月份,d是日数。1月和2月要按上一年的13月和14月来算,这时C和y均按上一年取值。
计算出来的结果模取7。  
 
具体设计处理:
程序中多处使用了子程序,在主程序接受用户的年、月输入时,用GetYearMonth,此子程序把得到的合法输入放到数据段中的year和month变量中。所谓的合法变量是指输入的是数字字符(不是字母或者其他的字符)。否则,程序提示用户输入错误,接受用户的再次输入,直到用户输入的信息合法或者按下ESC键为止。
在每次得到合法的年、月后,就调用打印模块的display函数,程序以后就一直在这里循环,每次调用BIOS的16h号中断的0号功能,读取键盘的一个按键,并根据题目要求对上下左右键做出相应的动作。直到用户按下ESC为止。
在打印模块的display中,首先要把display设为public属性,以示此过程要被别的模块调用。display的入口参数是BX(year),DL,(month),进入display后首先做一下现场的保护,然后把DS的值切换到打印模块里来。接着把BX,DL里的值放到内存变量中,以腾出BX,DL来使用。下面开始设置程序运行的界面:每次都从DOS窗口的(0,0)处开始显示,所以把光标每次开始都设置在(0,0)处。在设置整个屏幕上的显示属性,使用10h号中断的6号功能。BH的性质如下:
bit0~2 : 字体颜色 (0:黑,1:蓝,2:绿,3:青,4:红,5:紫,6:综,7:白)
bit3 : 字体亮度 (0:字体正常,1:字体高亮度)
bit4~6 : 背景颜色 (0:黑,1:蓝,2:绿,3:青,4:红,5:紫,6:综,7:白)
bit7 : 字体闪烁 (0:不闪烁,1:字体闪烁)
接下来设置星期六、日两列的字体为红色。也是使用10h中断的6号功能。
然后打印出当前显示的是哪一年的哪一月,调用dispYM,即打印两个十进制数。
然后就可以打印出MON,TUR等字样,以标注哪天是星期几。
然后,计算出当前月的天数,调用GetMonthSize,把得到的结果放到数据段的MonthSize中。如果是1、2月,要根据 蔡勒公式进行变换。然后是计算当前月份的第一天是星期几的过程。计算出之后在屏幕上留下相应的空格(为了对齐!)。
剩下的就是根据Monthsize的大小进行循环的输出日期了,调用dispWeek,在此过程立,要注意一位数与两位数对格式的影响。另外,打印到星期天要输出换行。
具体程序代码
# 主模块:
; 月历打印
; 主程序设置好入口参数, BX= 年份, DL= 月份
; 调用子程序 display
;By wangrui
;2006-12-8
 
extrn display:far
 
Esccode   equ    01h
Up    equ 048h
Down equ    050h
Left equ 04bh
Right equ       04dh
 
dseg segment
      Year     dw 0
      Month    db 0
      temp     db 10 dup(0)
      count dw ?
      ErrMsg   db 0dh,0ah,"The input NOT decimal! $"
dseg ends
 
cseg segment
      assume cs:cseg,ds:dseg
start:
      mov ax,dseg
      mov ds,ax
 
      call GetYearMonth
 
Ws:
      mov bx,Year
      mov dl,Month
      call far ptr display
again:
      mov ah,0
      int 16h
      cmp ah,Esccode
      je Exit
      cmp ah,Up
      je NextY
      cmp ah,Down
      je PreY
      cmp ah,Left
      je PreM
      cmp ah,Right
      je NextM
      jmp again
 
NextY:
      inc Year
      jmp Ws
PreY:
      dec Year
      jmp Ws
NextM:
      inc Month
      cmp Month,12
      jbe skip0
      mov Month,1
      inc Year
skip0:
      jmp Ws
PreM:
      dec Month
      cmp Month,1
      jae skip1
      mov Month,12
      dec Year
skip1:
      jmp Ws
 
Exit:
      mov ah,4ch
      int 21h
 
;**************************************************
 
GetYearMonth      proc    near
      push ax
      push cx
1. 时间日期切换显示: 我们设计了三种显示模式 操作:在主程序待机运行中,按下按键2,主程序进入日期显示(动态),默认显示方式为日期时间跳变显示,按1键在三种模式间切换,具体效果如下: 模式一日期、时间跳变切换效果:显示时间(4秒)=>显示年(1秒)=>显示月日(1秒)=>显示时间… 模式二日期、时间流水显示效果:显示内容为年月日时分秒从右往左进入显示区(1秒1位),时分秒出现后停留显示6秒,清屏重新显示。 模式三日期、时间滚屏显示效果:年、月日、时间由显示区由上向下循环滚动出现,移入移出速度为0.4s,中途停留显示3.6s。 2. 闹钟、整点报时: 闹铃可以设置3个,分别有独立开关状态(ON/OFF),可同时自主设定开启关闭使用某个闹钟,避免闹钟不够用的尴尬。响铃若无按键按下会持续1分钟。 整点报时按照12进制来进行,报时的时候1秒鸣,1秒断。 3. 时间显示方面优化 闪烁显示:设置时间或者闹钟时,选中的时段会闪烁,界面友好。 更新显示:设置状态当更改了当前时段,当前时段会立刻显示(处于闪烁的亮状态)。 保持显示:当按键按下中断进入键盘处理时,仍然可以继续显示原有内容,由此至终显示不会中断。 总的来说,在创新方面我们主要将精力放于优化显示方面上来,力求界面友好,凸显个性化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值