汇编之万年历课程报告.docx
《汇编之万年历课程报告.docx》由会员分享,可在线阅读,更多相关《汇编之万年历课程报告.docx(22页珍藏版)》请在冰豆网上搜索。
汇编之万年历课程报告
汇编课程设计报告
一、系统封面设计
设计思路:
设置80X25黑白文本方式,设置光标位置,将要显示的信息存入存储区中,用9号调用显示信息。
程序如下:
STACKSEGMENTSTACK
DB200DUP(0)
STACKENDS
DATASEGMENT
ADB'WANNIANLICHENGXUXITONG','$'
BDB'SHEJIRIQI:
2009.9.10','$'
CDB'SHEJIZHE:
ZHOUYANG','$'
DDB'070104021124','$'
EDB'JIKE2BAN','$'
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,SS:
STACK,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
ABCMACRO;定义ABC为宏,显示DX中的内容并设置光标位置
MOVAH,9
INT21H
POPDX
ADDDH,3H
MOVAH,2
INT10H
PUSHDX
ENDM
MOVAH,0;设置80X25黑白文本方式
MOVAL,2
INT10H
MOVAH,15
INT10H
MOVBL,7
PUSHBX
MOVAH,2
MOVDX,0412H
INT10H
PUSHDX
LEADX,A;依次显示题目名称,设计日期,设计者姓名、学号及专业班级
ABC
LEADX,B
ABC
LEADX,C
ABC
LEADX,D
ABC
LEADX,E
ABC
MOVAH,1;任意输入一个字符后结束
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
系统封面如下:
二、输入画面设计
设计思路:
1、密码及口令:
输入用10号调用,核查用串比较指令,修改则是先显示提示信息,再用无条件转移指令使重输入数据;2、年份:
输入用10号调用,再判断输入的年份是否为4位,不为4位则使重输,否则,再依次判断这4位是否均为整数,一旦发现有一位不为整数就重输。
程序如下:
DATASEGMENT
BDB'9999';B存储区中存放的是密码
N1EQU$-B
EPDB'1111';C存储区中存放的是口令
N2EQU$-EP
DDB'INPUTSUCCESFULLY!
$'
HDB'SHOWCALENDAR!
$'
GDB'FAILTOTNPUT!
$'
DATDB'PLEASEINPUTMIMA:
$'
DAT1DB'PLEASEINPUTKOUNING:
$'
DAT2DB'PLEASEINPUTYEAR:
$'
BUF1DB81
DB?
DB81DUP(0)
FUBDB81
DB?
DB81DUP(?
)
FPDB'******************$'
BUFDB'SUNMONTUEWEDTHUFRISAT$'
DATAENDS
STACKSEGMENTSTACK
DB200DUP(0)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,SS:
STACK,DS:
DATA,ES:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVES,AX
MOVAH,0;设置80X25黑白文本方式
MOVAL,2
MOVAH,15
INT10H
MOVSI,BX
PUSHSI
MOVAH,2
MOVDX,0412H
INT10H
PUSHDX
SUCCMACRO;定义SUCC为宏,调用宏AA,并显示D中信息,
AA再调用AA
LEADX,D
MOVAH,9
INT21H
AA
ENDM
AAMACRO;设置光标位置
POPDX
INCDH
MOVAH,2
INT10H
PUSHDX
ENDM
FAILMACRO;显示“失败”信息
AA
LEADX,G
MOVAH,9
INT21H
AA
ENDM
LEADX,DAT
MOVAH,9
INT21H
INPUT:
LEADX,BUF1;输入密码
MOVAH,10
INT21H
CMPBUF1+1,N1;核查输入数据位数与密码位数是否相等,若不等则
JECOT重输,否则转COT,再依次比较各位是否都相等;
FAIL若是,则转NEXT,进行口令输入,否则重输。
JMPINPUT
COT:
LEASI,B
LEADI,BUF1+2
CLD
CMPSB
JZNEXT
FAIL
JMPINPUT
NEXT:
SUCC
LEADX,DAT1;输入口令,其核查及修改同密码的核查与修改
MOVAH,9
INT21H
INPU1:
LEADX,BUF1
MOVAH,10
INT21H
CMPBUF1+1,N2
JECOT1
FAIL
JMPINPU1
COT1:
LEASI,EP
LEADI,BUF1+2
CLD
CMPSB
JZNEXT0
FAIL
JMPINPUT
NEXT0:
SUCC
YEAR:
LEADX,DAT2
MOVAH,9
INT21H
LEADX,FUB;输入年份并首先判断其位数是否为4
MOVAH,10
INT21H
LEASI,FUB+2
MOVCX,4
MOVAL,4
CMPAL,FUB+1
JECOM;若输入数据为4位则转COM,否则重输
FAIL
JMPYEAR
COM:
CMP[SI],BYTEPTR30H;依次判断输入的各位数据是否均为整数,若是则
JNBY1将屏幕上滚十行,否则重输
AA
JMPYEAR
Y1:
CMP[SI],BYTEPTR39H
JBEY2
AA
JMPYEAR
Y2:
INCSI
LOOPCOM
SUCC
LEADX,H
MOVAH,9
INT21H
MOVAH,1
INT21H
MOVAH,6;将屏幕上滚十行
MOVAL,10
MOVCX,0
MOVDH,24
MOVDL,79
INT10H
MOVAH,2;设置光标位置
MOVDX,1
INT10H
PUSHDX
LEASI,FUB+2;将输入的年份用串传送指令将各位依次送到
LEADI,FP+3FP存储区中
MOVCX,4
CLD
REPMOVSB
LEADX,FP;显示日历的横幅,包括年、月及星期
MOVAH,9
INT21H
MOVAH,2
POPDX
INCDH
INT10H
PUSHDX
LEADX,BUF
MOVAH,9
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
输入画面如下:
三、日历输出
设计思路:
1、设计一子程序求X年为平年还是闰年,以确定二月的总天数;
2、设计一子程序将X、Y转化为十进制数;
3、设计一子程序求X年Y月Z日是星期几,事实上只需求出X年Y月1日是星期几,其他天
均可由1日求得。
具体而言就是,由X年Y月1日的星期数确定其在日历图上的位置,便将光标设置在该位置处,再由日历图上每一行靠内的相邻两日之间的距离相等,以出2日、3日等的位置
4、将输出一个月日历的程序段的入口参数尽量减少,最好是仅有X、Y,且是X、Y的一种形式,使其可循环生成一年的日历
程序如下:
DATASEGMENT
XDW2008;X中存放的是年份
YDB4;Y中存放的是月份
YUEDW30;YUE中存放的是Y月的总天数
NDB?
;N中存放的是X年Y月1日的星期数
EEDB'10$'
NNDB?
TODW?
T1DW1000
T2DW100
T3DB10
TPDB4DUP(?
)
FCDW14DUP(?
)
BBDB10
E0DW400
F0DW100
G0DW4
FUBDB81
DB?
DB81DUP(?
)
YUFDB6
DB?
DB6DUP(?
)
YUF1DB6
DB?
DB6DUP(?
)
FPDB'***2008***************4***$'
BUFDB'SUNMONTUEWEDTHUFRISAT$'
P1DW'2'
P2DW'1','3','5','7','8',3AH,3CH
N0EQU$-P2
P3DW'4','6','9',3BH
N1EQU$-P3
ADW0,31,59,90,120,151,181,212,243,273,304,334
FADB'INPUTWRONG!
',0AH,0DH,'$'
FA1DB'INPUTWRONGDAY!
',0AH,0DH,'$'
YUDB'PLEASEINPUTMOON!
',0AH,0DH,'$'
DATAENDS
STACKSEGMENTSTACK
DB200DUP(0)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,SS:
STACK,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX;设置80X25黑白文本方式
MOVAH,0
MOVAL,2
MOVAH,15
INT10H
MOVBL,7
MOVSI,BX
PUSHSI
MOVAH,2
MOVDX,1
INT10H
PUSHDX
SUCCMACRO;设置光标位置并显示“成功”信息
AA
LEADX,D
MOVAH,9
INT21H
AA
ENDM
AAMACRO;设置光标位置
POPDX
INCDH
MOVAH,2
INT10H
PUSHDX
ENDM
FAILMACRO;设置光标位置并显示“失败”信息
AA
LEADX,G
MOVAH,9
INT21H
AA
ENDM
LEADX,FP;显示一月日历的年、月及星期
MOVAH,9
INT21H
AA
LEADX,BUF
MOVAH,9
INT21H
CALLPINGRUN;求X年是平年还是闰年,若是平年则将DI置
MOVTO,DI0,否则置1
MOVNN,'1';将一日的形码送到NN中存放
CALLFIND_Y;求C
MOVBX,DX
INCBX
CMPY,2
JBEXXX
ADDBX,TO;BX中的值为C
XXX:
MOVCX,X;将年份X放入CX中
CALLDAY;子程序DAY的入口参数为X和C,出口参
MOVN,DL数为N(星期数)
POPDX;定X年Y月一日在日历图上的光标位置
POPBX
MOVAL,4
MULN
MOVDL,AL
ADDDL,2
INCDH
MOVAH,2
INT10H
LEASI,EE
MOVDI,1
SHW:
PUSHDX;用9号调用(显示字符)依次显示1到9这几
MOVAL,NN日,到10时开始用9号调用(显示字符串)
MOVAH,9
MOVCX,1
INT10H
INCDI
ADDNN,1H
CMPNN,39H
JASH2
POPDX;查看光标位置是否超过日历图的右边缘,若
CMPDL,22是则转下一行,否则行号不变列号怎加
JBESH1
INCDH
MOVDL,2
MOVAH,2
INT10H
JMPSHW
SH1:
ADDDL,4
MOVAH,2
INT10H
JMPSHW
SH2:
CMPDI,YUE;判断Y月是否显示完毕,若是则任输
JATER一字符后结束,否则继续显示
POPDX
CMPDL,22
JBESH11
INCDH
MOVDL,2
MOVAH,2
INT10H
PUSHDX
JMPHHH
SH11:
ADDDL,4
MOVAH,2
INT10H
PUSHDX
HHH:
LEADX,EE;显示10以上的数据是将其以字符串的形式显
MOVAH,9示,低地址存放数据的高位,高地址存放数据
INT21H的低位数字,在该该存储区EE中初值为‘10’
INCDI从10开始增加,高地址数据先增,低地址的
ADD[SI+1],BYTEPTR1后增,且用DI做计数器,每当(DI)达到十
CMPDI,10的整数倍时,低地址数据加1,同时高地址数
JEDDA置‘0’
CMPDI,20
JEDDA
CMPDI,30
JEDDA
JMPSH2
DDA1:
MOV[SI+1],BYTEPTR30H
JMPSH2
DDA:
ADD[SI],BYTEPTR1
JMPDDA1
TER:
MOVAH,1
INT21H
MOVAH,4CH
INT21H
PA10PROC;将从键盘输入一个或两个字符化为十进制数
MOVDI,SI
MOVAL,2
CMPAL,[SI+1]
JAPP2
SUBBYTEPTR[SI+2],30H
MOVAL,[SI+2]
MULBB
SUBBYTEPTR[SI+3],30H
MOVBL,[SI+3]
MOVBH,0
ADDAX,BX
JMPEXIT2
PP2:
MOVAL,[DI+2]
SUBAL,30H
MOVAH,0
EXIT2:
RET
ENDP
PINGRUNPROC;入口参数为年份X,利用满足式子X%400=0或X%4=0
MOVAX,X且X%100!
=0就为闰年,否则就是平年。
若是平年,
MOVDX,0就将0赋给DI,反之送1
DIVE0
CMPDX,0
JZSS2
MOVAX,X
MOVDX,0
DIVF0
CMPDX,0
JESS1
MOVAX,X
MOVDX,0
DIVG0
CMPDX,0
JESS2
SS1:
MOVDI,0
JMPEXIT0
SS2:
MOVDI,1
EXIT0:
RET
ENDP
FIND_YPROC;令X年Y月Z日是这一年的第C天,M=X—1+
LEASI,A(X—1)/4—(X—1)/100+(X—1)/400,总
MOVBH,Y天数为S,则有S=M+C,星期数N=S%7
MOVBL,1
FIND:
CMPBH,BL
JENP
INCBL
ADDSI,2
CMPBL,12
JBEFIND
LEADX,FA
MOVAH,9
INT21H
EXIT3:
RET
NP:
MOVDX,[SI]
JMPEXIT3
ENDP
DAYPROC;(CX)=X,(BX)=C,通过式子S=M+C和N=S%7得到
MOVAX,CXN,此子程序的最终结果N在DX中
MOVDX,0
DECAX
MOVSI,AX;(SI)=X-1=(DI)
MOVDI,AX
MOVDX,0
DIVG0
ADDSI,AX;(SI)=(SI)+(X-1)/4
ADDSI,BX
MOVAX,DI
MOVDX,0
DIVF0
SUBSI,AX;(SI)=(SI)-(X-1)/100
MOVAX,DI
MOVDX,0
DIVE0
ADDSI,AX;(SI)=(SI)+(X-1)/400
MOVAX,SI
MOVDX,0
MOVBX,7
DIVBX;(DX)=S%7=N
RET
ENDP
CODEENDS
ENDSTART
日历图如下:
四、
A、程序系统总体功能模块调用图及模块功能说明:
封面:
设置80X25黑白文本方式—》2号调用设置光标位置、9号功能调用显示封面信息
输入画面:
设置80X25黑白文本方式
B、程序系统详细的程序框图(每个子程序的流程图);
在程序系统中有如下几个子程序:
PA10、PINGRUN、FIND-Y、DAY,它们的流程图分别如下:
PA10:
将从键盘输入一个或两个字符化为十进制数
其流程图如下:
PINGRUN:
入口参数为年份X,利用满足式子X%400=0或(X%4=0且X%100!
=0)就为闰年,否则就是平年。
若是平年,就将0赋给DI,反之送1
其流程图如下:
FIND-Y:
令X年Y月Z日是这一年的第C天,M=X—1+(X—1)/4—(X—1)/100+(X—1)/400,总天数为S,则有S=M+C,星期数N=S%7
LEASI,A
MOVBH,Y
MOVBL,1
其程序流程图如下:
CMPBH,BL
DAY:
(CX)=X,(BX)=C,通过式子S=M+C和N=S%7得到N,此子程序的最终结果N在DX中
其程序流程图如下:
MOVAX,年份,MOVBX,C
MOVDX,0,DECAX,
MOVSI,AX,MOVDI,AX
MOVDX,0,DIVG0
结束
五、系统设计及实现的技术特点、不足及改进的建议:
在系统设计及实现的技术上,一度让我头疼的是面对明显错误的程序不知错在哪里,渴望有一种东西专门用来指出错误在哪里,在没有这种东西的情况下,我也想了一种办法,那就是使用提示信息,在不同的位置放上它可以找出一些错误,但这种方法耗时耗力,而且有些错误还是发现不了。
例如本次作业中我做了一个显示X年Y月的日历的主程序,但将其转变成子程序就出问题。
本次作业的不足之处在于这一点,如果解决了这一点,就可以在仅输入年份的情况下输出一年的日历,也可以在输入年份及月份的情况下输出一个月的日历。
六、课程设计的体会要点:
通过此次课程设计,我了解到课程设计是一门非常讲究思路严谨的课程,在设计的过程中不仅让我对所学知识进行更深一步的了解,比如说宏与子程序,对于它们的区别我原以为已经了解清楚了,但这次编程上机后我才发现自己了解的实在微乎其微,宏可以调用子程序吗?
子程序可以调用宏吗?
两者在程序中的位置呢?
以前都没有想过这些问题,所以我发现上机可以学到许多书本上学习不到的地方。
而且,编程需十分严谨,一旦有一种情况没有顾虑到就可能产生很大的错误。
另一方面,我觉得编程可以让我们的思维严谨。
在不断写程序、该程序的过程中我受益良多。
编程的这段日子是我大学以来最充实的日子,我很累,但很开心。