利用汇编语言判断闰年生肖及星座.docx
《利用汇编语言判断闰年生肖及星座.docx》由会员分享,可在线阅读,更多相关《利用汇编语言判断闰年生肖及星座.docx(17页珍藏版)》请在冰豆网上搜索。
利用汇编语言判断闰年生肖及星座
汇编语言与接口技术大作业
题目:
基于汇编语言的闰年判断程序设计,年份生肖判断,以及星座查询系统
专业班级:
姓名:
学号:
2013年06月
基于汇编语言的闰年年份生肖及星座判断程序设计
第一章设计方案
一、设计内容
根据提示信息输入任意年份,
编写判断闰年的程序,如果是闰年,则在屏幕上输出“Thisisaleapyear”,否则显示“Thisisn’taleapyear”;
在输入年份的基础上,进一步判断年份生肖,并输出“thisisa…year!
”;
进而根据提示输入月日,进行星座系统查询,并输出相应星座的英语拼写。
二、设计分析
利用DOS21H中断类型的10号键盘功能调用,将键盘接受到的年份数值的字符串按字节存入缓冲区。
将字符串中的每个字符转换为对应的十进制数值(利用0-9这10个数的ASCⅡ码值比其本身大30H的关系),判断某年为闰年的汇编语言表达式为:
(((AX)MOD4EQ0)AND((AX)MOD100EQ0))OR((AX)MOD400EQ0)其中,(AX)中存放的是从键盘输入的年份值。
在本程序运行后,只要输入年份就能判断是否为闰年。
在输入年份已经转化为十进制数值的基础上,考虑到公元4年是鼠年,生肖属性12年一轮回,我们先对输入的年份减4再除以12并取余,根据余数的不同进行不同的输出。
在输入月和日之后,先将输入的前两位转换为月份,再将输入的末两位转化为日期,再根据月份和日期进行星座判断。
三、程序流程图
本框图列出了此次课程设计的总流程,显示信息,输入数据,判断格式,判断闰年和结束程序。
客观显示了设计的顺序结构,循环结构及分支结构。
程序流程图设计
一、程序分析
主程序:
显示提示输入年份以及输入的字符内容,和最后输出的判断。
子程序:
1.判断输入:
该模块是对输入的年份的格式的判断,若是错误则显示错误Error,正确则进行下面的操作。
2.字符串转换格式:
将数字字符串转换成数字,以便进行下面的程序操作。
3.判断闰年:
判断输入的年份是否为闰年,若是则输出“Thisisaleapyear!
”,若不是则输出“Thisisnotaleapyear!
”,然后退出。
二、汇编程序
.modelsmall
.386
DIPMSGMACROMSG;输出信息的宏定义
PUSHDX
PUSHDS
MOVDX,SEGMSG
MOVDS,DX
LEADX,MSG
MOVAH,09h
INT21H
POPDS
POPDX
ENDM
datasegment
infondb0dh,0ah,'inputayear:
$';闰年输出信息
Ydb0dh,0ah,'Thisisaleapyear!
$'
Ndb0dh,0ah,'Thisisnotaleapyear!
$'
Edb0dh,0ah,'Inputyearhaserror!
$'
ratdb0dh,0ah,'Thisistheyearofrat!
$'年份生肖输出信息;
oxdb0dh,0ah,'Thisistheyearofox!
$'
tigerdb0dh,0ah,'Thisistheyearoftiger!
$'
rabbitdb0dh,0ah,'Thisistheyearofrabbit!
$'
dragondb0dh,0ah,'Thisistheyearofdragon!
$'
snakedb0dh,0ah,'Thisistheyearofsnake!
$'
horsedb0dh,0ah,'Thisistheyearofhorse!
$'
sheepdb0dh,0ah,'Thisistheyearofsheep!
$'
monkeydb0dh,0ah,'Thisistheyearofmonkey!
$'
chickdb0dh,0ah,'Thisistheyearofchick!
$'
dogdb0dh,0ah,'Thisistheyearofdog!
$'
pigdb0dh,0ah,'Thisistheyearofpig!
$'
wdw0;用于保存输入的年份的数值,因为输入的年份是字符串,因此需要转换为数
bufdb8;定义输入缓冲区
db?
db8dup(?
)
BUF1db6
db?
db6DUP(0)
MESS1DB'PleaseENTERTHEMONTHANDDATE(bothincludetwonumbers):
DIVIDEDBy/',13,10,'$'
ARRDB19,18,20,20,20,21,22,23,22,22,21,21;星座输出信息
ARR1DB31,29,31,30,31,30,31,31,30,31,30,31
MESS2DB'ENTERWRONG!
!
!
',13,10,'$'
FUNCDB'CAPRICORN$'
DB'AQUARIUS$'
DB'PISCES$'
DB'ARIES$'
DB'TAURUS$'
DB'GEMINI$'
DB'CANCER$'
DB'LEO$'
DB'VIRGO$'
DB'LIBRA$'
DB'SCORPIO$'
DB'SAGITTARIUS$'
DB'CAPRICORN$',13,10,'$'
tabdws0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11
dataends
stacksegmentstack
db200dup(0)
stackends
codesegment
assumeds:
data,ss:
stack,cs:
code
.startup
DIPMSGinfon
leadx,buf;从键盘输入年份字符串
movah,0Ah;0AH功能调用从键盘接受字符串到内存的输入缓存区
int21h
movcl,[buf+1]
movbl,cl
movzxcx,bl;把输入的字符的个数保存在cl中
leadi,buf+2;把从键盘输入字符的首地址存放到di中
pushax
a0:
;实现检错功能
moval,[di]
cmpal,0dh;换行,回车
jza1
cmpal,'9'
jga3
cmpal,'0'
jla3
incdi
jmpa0
a1:
popax
calldatacate;调用datacate子程序
callifyears;调用ifyears子程序
jca2;如果进位则跳转
DIPMSGn
jmpexit
a2:
DIPMSGy;输出是闰年
jmpexit
a3:
DIPMSGe;错误提示
exit:
nop
pushcx
pushax
pushbx
movcx,w
movax,cx
movdx,0
subax,4
movbx,12
divbx
shldx,1
leabx,tab
addbx,dx
jmpnearptr[bx]
s0:
DIPMSGrat
jmpOVER
s1:
DIPMSGox
jmpOVER
s2:
DIPMSGtiger
jmpOVER
s3:
DIPMSGrabbit
jmpOVER
s4:
DIPMSGdragon
jmpOVER
s5:
DIPMSGsnake
jmpOVER
s6:
DIPMSGhorse
jmpOVER
s7:
DIPMSGsheep
jmpOVER
s8:
DIPMSGmonkey
jmpOVER
s9:
DIPMSGchick
jmpOVER
s10:
DIPMSGdog
jmpOVER
s11:
DIPMSGpig
OVER:
popbx
popax
popcx
MOVDL,0DH;回车换行
MOVAH,2
INT21H
MOVDL,0AH
MOVAH,2
INT21H
DIPMSGMESS1
MOVDX,OFFSETBUF1
MOVAH,0AH
INT21H
LEASI,BUF1
MOVDI,0
LEABP,FUNC
MOVAL,0;将月份转化为十进制
SUBBYTEPTR[SI+2],30H
ADDAL,BYTEPTR[SI+2]
MOVCL,10
MULCL
SUBBYTEPTR[SI+3],30H
ADDAL,BYTEPTR[SI+3]
MOVCH,1
CALLSTAR
LEADX,[BP];将相应的星座输出
MOVAH,9
INT21H
MOVDL,0DH;回车
MOVAH,2
INT21H
MOVDL,0AH;换行
MOVAH,2
INT21H
.exit
datacateprocnear;用于把表示年份的字符串转换为数值
pushcx;
deccx;让cx寄存器自减1
leasi,buf+2;把字符串的首地址保存在源地址寄存器SI中让si指向字符串的最低位
p1:
incsi
loopp1;将si指向输入的最后一个值
popcx
movdh,30h
movbx,10
movax,1
movdh,0
p2:
pushax
subbyteptr[si],30h;ASCII码字符,减去30H后转换十进制数
movdl,[si]
muldx;计算某一位上的值
addw,ax;把计算结果累加,并保存在w中
popax;出栈操作,去除上一次操作后的倍数
mulbl;乘以bl,计算当前的倍数
decsi;修改源地址寄存器si的值,使得si指向下一个字符(即高位)
loopp2;循环直到所有字符处理完毕(
ret;子程序返回指令
datacateendp
ifyearsprocnear;此子程序用来判断年份是否为闰年
pushbx
pushcx
pushdx
movax,w;把转换后的年份的数值存入AX
movcx,ax
movdx,0;将dx清零
movbx,4;把4存放到寄存器bx中(除数)
divbx;除法指令
cmpdx,0;将dx中的余数与0进行比较,看似否整除
jnzlab1;若不相等跳转
movax,w;判断年份是否位100的整数倍
movbx,100;将100赋给bx寄存器,做div的源操作数
divbx
cmpdx,0;将dx中的余数与0进行比较,看似否整
jnzlab2;余数非零则跳转
movax,cx;判断年份是否是400的倍数
movbx,400
divbx
cmpdx,0
jzlab2
lab1:
clc;清除进位标志,即非闰年
jmplab3
lab2:
stc;设置进位标志,即闰年
lab3:
popdx
popcx
popbx
ret;子程序返回指令
ifyearsendp
STARPROCnear
P:
CMPAL,12
JAP2
CMPAL,CH
JEP1
INCCH
INCDI
INCBX
ADDBP,12
JMPP
P1:
MOVAL,0;将月份转化为十进制并判错
SUBBYTEPTR[SI+5],30H
ADDAL,BYTEPTR[SI+5]
MOVCL,10
MULCL
SUBBYTEPTR[SI+6],30H
ADDAL,BYTEPTR[SI+6]
CMPAL,ARR1[DI]
JAP2
CMPAL,ARR[DI]
JBEP3
ADDBP,12
JMPP3
P2:
LEADX,MESS2
MOVAH,9
INT21H
P3:
MOVDL,0DH
MOVAH,2
INT21H
MOVDL,0AH
MOVAH,2
INT21H
EXITS:
RET
STARENDP
codeends
end
第二章程序调试
由于所编写程序较大,我先对程序实现的不同模块(即子程序)先分别设计和调试,在确定各模块运行和输出正确后,将各模块进行拼接和整体上的调试。
在Masmforwindows集成环境2012软件中调试,运行上面的程序,初始界面:
如图4-1
图4-1
输入年份1900执行程序,回车换行,则显示Thisisn’taleapyear;并同时给出了年份对应的生肖,显示Thisistheyearofrat;如果输入错误,如abcd则显示Inputillegal!
并提示用户继续月份和日期,输入09/10,回车换行,则显示VIRGO,结束操作。
运行界面:
如图4-2
图4-2
当输入年份1999时,显示Thisisn’taleapyear,
Thisistheyearofrabbit;并提示输入月份和日期,当输入01/24日后,输出显示
AQUARIUS