8086计算器仿真分享借鉴Word文档格式.docx
《8086计算器仿真分享借鉴Word文档格式.docx》由会员分享,可在线阅读,更多相关《8086计算器仿真分享借鉴Word文档格式.docx(25页珍藏版)》请在冰豆网上搜索。
加法运算正确。
2.计算27-9的结果
依次按下2、7、-、9、=,在显示器上显示出结果:
18。
减法运算正确。
3.计算15*2的结果
依次按下1、5、*、2、=,在显示器上显示出结果:
30。
乘法运算正确。
4.计算56/8的结果
依次按下5、6、/、8、=,在显示器上显示出结果:
7。
除法运算正确。
第二步:
对实现每按一次按键蜂鸣器发一次预定声音功能的测试。
执行后,按下按键蜂鸣器出声则此功能可以正常实现。
第三步:
对实现幂运算的功能进行测试
计算
的结果
依次按下8、^、3,在显示器上显示出结果:
524。
幂运算正确。
第四步:
对计数功能进行测试
使整个电路开始工作,按下自动计数开始的按钮,计数开始,到8结束,蜂鸣器发声提示时间到。
此功能执行成功。
第五步:
手动计数加1和减1的功能测试
按下手动加1按钮,数码管上显示的值加1,按下手动减1按钮,数码管上显示的值减1。
功能执行正常。
八、关键技术
1.本实验利用子程序思想将整个程序模块化,使得程序清晰明了,并且调用方便,移植性好,升级简单;
2.运用矩阵键盘扫描和键值比较确保每一个键都能够被8086及时检测到并正确识别;
3.用大循环将整个程序反复执行,保证程序按设计执行,不会出现跑飞的情况;
4.正确设置8255A工作方式,是8086读取键盘值和送数至数码管高效正确执行。
九、实际完成功能
通过硬件电路的搭接和汇编程序的设计,我们设计出的计算器可以正确的完成以下功能:
1.对加、减、乘、除的基本运算。
通过键盘输入并显示要计算的数字和执行的运算,通过数码显示器显示计算结果;
2.实现每次按下按钮时蜂鸣器都能发出声响。
表明已有按键按下,可以根据声响的次数来判断输入数字的个数和是否误输的情况,有效避免和降低了用户错误的发生;
3.实现求幂运算的功能。
通过键盘输入底数和幂次,由数码显示器显示计算结果,在简单计算器的基础上,实现了更高级的运算,实用性增强;
4.实现从计数的功能,并有自动计数、手动加1计数和手动减1计数功能可供选择。
按下自动计数键,电路便开始实现计数的功能并由数码显示器显示,计数到预定值时停止并提示用户。
十、总结(任务分工等)
通过小组人员的共同努力,我们顺利实现了计算器的预计全部功能,并在此基础上增加了一些实用的功能。
我们小组的任务分工如下:
在本次的实验中,使我们熟练地掌握了Proteus软件的运用,对课本的知识理解更加深刻。
学会了运用所学的知识来解决实际的问题,积累了一些动手实践的经验。
在上课时学习的都是基本的程序设计,没有什么子程序,程序短而且简单,分析起来不困难。
而在本实验中,要求设计的是一个完整的系统,这就要求我们从系统出发,把视野放在整体上,力求各个子模块之间的相互协调和配合,共同组成完整可行的系统。
本次实验一改以往做实验的风格,通过一个大的综合实验和小组结对的方式,给学员更多的自由发挥空间,使学员的许多方面得到了锻炼。
在一个系统中,不是通过各个子模块的简单堆积就能够实现整体的功能,而是各个模块相互协调,发挥各自的功能,才能完美实现所需要的功能。
因此,本实验其实难度更大,也更有实际意义。
其实际意义早已超越了实验本身。
通过一个综合实验,我们更加充分的理解了课本的程序语句,不仅知道各条语句之间的相同点,也理解了在不同条件下它们的不同作用。
本实验在做的过程中,我们从一个更高的层次对课本的知识进行了一遍详细的梳理。
这次实验,不管是对于课本的学习,还是今后参加工作或者参加电子设计,都有很大的意义。
十一、附录实验程序源码
DATASEGMENT
XDB?
?
;
存放数据的每一位
X1DW?
存放第一个数据值
X2DW?
存放第二个数据值
YDW?
存放运算结果
SDB?
存放运算符号值
EDB?
按下等号键标记
CCDB?
存放运算数据位数
HDB0;
存放按键行号
LDB0;
存放按键列号
SJISZHIDB?
存放计数值的变量
DISCODEDB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H;
段码表
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVSJISZHI,0
MOVAL,90H;
设置为A口输入,B口输出,C口输出
OUT46H,AL
MOVDI,OFFSETX+3;
DI指向X的高位
KKK:
CALLKEY;
扫描按键
JMPKKK
;
以下为按键扫描子程序,程序返回后,在变量H和L中存放当前按键的行列号
KEYPROC
CHECK:
CALLDISP;
等待按键按下的同时进行显示
MOVAL,0F0H;
所有行输出低电平
OUT44H,AL
INAL,40H
CMPAL,0FFH;
读列值
JZCHECK;
若都为高电平则无键按下,等待
MOVCX,50
LOOP$;
延时消抖
INAL,DX;
重读列值
CMPAL,0FFH
无键按下一直等待
MOVH,0;
有键按下,先把行列号变量清0
MOVL,0
MOVBL,01H
MOVBH,0FEH;
扫描法读键值:
从第一行开始测试,即PC0输出低电平
NEXT:
MOVAL,BH
NEXTH:
INAL,40H;
读列值,判断是第几列有键按下
TESTAL,BL;
从第一列开始判断
JZWAIT0
ROLBL,1
CMPBL,20H;
当前行状态下没有任何列有键按下,则转为对下一行的测试
JZNEXTL
INCH;
每判断一列,列号加1
JMPNEXTH;
再对下一列进行判断
NEXTL:
MOVH,0
ROLBH,1;
对下一行测试,让下一个PC口输出低电平
CMPBH,0EFH
JZEXIT
INCL
JMPNEXT
WAIT0:
若有键按下,则等该按键松开后再计算键值
JNZWAIT0
CALLKEYVALUE;
调计算键值子程序
EXIT:
RET
KEYENDP
以下为计算键值子程序,通过行列号计算键值(键值=列号*5+行号)
键值存放在DL寄存器中
KEYVALUEPROC
PUSHAX
MOVAL,0FFH
OUT42H,AL
CALLDELAY
MOVAL,00H
POPAX
MOVDL,L
MOVDH,H
MOVAL,5
MULDL;
列号乘5
MOVDL,AL
ADDDL,DH
CMPDL,0
JZQI
CMPDL,1
JZBA
CMPDL,2
JZJIU
CMPDL,5
JZSH
CMPDL,6
JZWU
CMPDL,7
JZLIU
CMPDL,9
JZJISHU_CALL;
自动计数
CMPDL,10
JZYI
CMPDL,11
JZER
CMPDL,12
JZSAN
CMPDL,14
JZSJI_CALL;
手动加1
CMPDL,15
JZCLR_CALL;
按下的是清除键
CMPDL,16
JZLIN
CMPDL,17
JZOUTP_CALL;
按下的是等于键
CMPDL,19
JZSJIJ_CALL;
手动减1
JMPCONT_CALL
SH:
MOVDL,4
CALLNUMBER
JMPEXIT1
WU:
MOVDL,5
LIU:
MOVDL,6
CALLNUMBER
JMPEXIT1
QI:
MOVDL,7
CALLNUMBER
JMPEXIT1
BA:
MOVDL,8
JIU:
MOVDL,9
YI:
MOVDL,1
CALLNUMBER
JMPEXIT1
ER:
MOVDL,2
SAN:
MOVDL,3
LIN:
MOVDL,0
JMPEXIT1
CLR_CALL:
CALLCLEAR;
调清除键处理子程序
JISHU_CALL:
CALLZJIS;
调用自动计数子程序
SJIJ_CALL:
DECSJISZHI;
调用减1计数字程序
CALLSJI
SJI_CALL:
INCSJISZHI
CALLSJI;
调用手动计数子程序
NUM_CALL:
CALLNUMBER;
调数字键处理子程序
CONT_CALL:
MOVS,DL;
存放运算键的键值
MOVE,0
CALLCOUNT;
调运算键处理子程序,计算第一个加数
OUTP_CALL:
CALLOUTP;
调等号键处理子程序
JMPEXIT1
EXIT1:
KEYVALUEENDP
以下为清除键处理子程序,按下清除键后,X变量全部清0
CLEARPROC
MOVX[3],0
MOVX[2],0
MOVX[1],0
MOVX[0],0
CALLBITP
CLEARENDP
以下为等号键处理子程序,该子程序负责将第二个运算数据的数值计算出来存入X2变量
并根据运算符号,调用相应的运算子程序
OUTPPROC
PUSHAX
PUSHDX
PUSHBX
INCE
调运算键处理子程序,计算第二个运算数据
CMPS,18
JZADD_CALL;
运算符为加号,则调用加法子程序
CMPS,13
JZSUB_CALL;
运算符为减号,则调用减法子程序
CMPS,8
JZMUL_CALL;
运算符为乘号,则调用乘法子程序
CMPS,3
JZDIV_CALL;
运算符为除号,则调用除法子程序
CMPS,4
JZCF_CALL
ADD_CALL:
CALLADDP
JMPSTORE1
SUB_CALL:
CALLSUBP
MUL_CALL:
CALLMULP
CF_CALL:
CALLCFP
DIV_CALL:
CALLDIVP
STORE1:
MOVAX,Y;
以下程序将各运算子程序返回的运算结果,按位分解,送入X变量
MOVDX,0
MOVBX,1000
DIVBX
MOVX[0],AL
MOVAX,DX
MOVBL,100
DIVBL
MOVX[1],AL
MOVAL,AH
MOVAH,0
MOVBL,10
MOVX[2],AL
MOVX[3],AH
POPBX
POPDX
POPAX
OUTPENDP
以下为运算键处理子程序,该程序将第一个运算数据的数值计算出来并存入X1变量
或者将第二个运算数据的数值计算出来并存入X2变量
将运算符的值存入S变量
COUNTPROC
CALLBITP;
测试X中的数据是多少位
CMPCC,4;
输入的数据是4位数?
JZC4
CMPCC,3;
输入的数据是3位数?
JZC3
CMPCC,2;
输入的数据是2位数?
JZC2
JMPC1;
输入的数据是1位数?
C4:
MOVAX,0
MOVAL,X[0]
MULBX
MOVDX,AX
C3:
MOVAL,X[1]
MULBL
ADDDX,AX
C2:
MOVAL,X[2]
C1:
MOVAL,X[3]
CMPE,1
JNZX1_S
MOVX2,DX;
按下的是等号,则将第二个运算数据的值存入X2变量
JMPEXIT3
X1_S:
MOVX1,DX;
按下的是运算符号,则将第一个运算数据的值存X1变量
MOVX[3],0;
清空X变量
EXIT3:
COUNTENDP
以下为数字键处理子程序
该程序,将输入的数据按位存放在X变量中,并由CC记录数据的位数
NUMBERPROC
JNZCONTINUE
CALLCLEAR
CONTINUE:
CMPCC,0;
目前数据为0位,即没有数据,则转到SSS
JZSSS
若已有数据,以下程序将X左移8位。
例如:
先输入“1”,当再输入2时,
先要将“1”从个位移到十位,然后再将“2”存放到个位
MOVAH,X[2]
MOVDL,X[1]
MOVDH,X[0]
MOVCX,8
LL:
SHLAX,1
RCLDX,1
LOOPLL
MOVX[3],AL
MOVX[2],AH
MOVX[1],DL
MOVX[0],DH
SSS:
MOV[DI],DL;
将当前键入的数据存放到X的最低位
INCCC;
数据位数加1
判断数据位数
JNGEXIT2
MOVCC,0;
如果数据超过4位,重新从最低位开始存放
EXIT2:
调显示子程序,显示输入的数据
NUMBERENDP
加法子程序
ADDPPROC
MOVAX,X1
ADDAX,X2
MOVY,AX
ADDPENDP
减法子程序
SUBPPROC
SUBAX,X2
SUBPENDP
乘法子程序
MULPPROC
MOVDX,X2
MULDX
MULPENDP
除法子程序
DIVPPROC
MOVBX,X2
DIVPENDP
乘方子程序
CFPPROC
PUSHCX
MOVDX,X1
MOVCX,X2
DECCX
LP:
MOVDX,X1
LOOPLP
POPCX
POPDX
POPAX
CFPENDP
显示子程序,将X中的数值按位显示出来
DISPPROC
MOVBH,0
LEASI,DISCODE
测试X位数
CMPCC,4
JZQIAN
CMPCC,3
JZBAI
CMPCC,2
JZSHI
CMPCC,1
JMPG
QIAN:
MOVAH,11100000B;
从第4位开始显示
MOVBL,X[0]
MOVAL,[SI+BX]
OUT42H,AL
CALLDELY
MOVAL,0
BAI:
MOVAH,11010000B;
从第3位开始显示
MOVBL,X[1]
SHI:
MOVAH,10110000B;
从第2位开始显示
MOVBL,X[2]
G:
MOVAH,01110000B;
从第1位开始显示
MOVBL,X[3]
JMPEXIT4
EXIT4:
DISPENDP
分析数据位数子程序
BITPPROC
CMPX[0],0;
如果X[0]不为0,则数据为4位数
JNZFOURBIT
CMPX[1],0;
如果X[1]不为0,则数据为3位数
JNZTHREEBIT
CMPX[2],0;
如果X[2]不为0,则数据为2位数
JNZTOWBIT
CMPX[3],0;
如果X[3]不为0,则数据为1位数
JNZONEBIT
JMPZER0BIT;
否则,没有数据
FOURBIT:
MOVCC,4
JMPEXIT5
THREEBIT:
MOVCC,3
TOWBIT:
MOVCC,2
ONEBIT:
MOVCC,1
ZER0BIT:
MO