前言本次课程设计的题目是用汇编语言实现一个简单的计算器,要求:编写一个程序,每运行一次可执行程序,可以实现加减乘除四则运算。
计算器是最简单的计算工具,简单计算器具有加、减、乘、除四项运算功能。
通过使用汇编语言设计实现简单计算器,以此进一步了解和掌握对数据存储,寄存器的使用,加减乘除相关指令以及模块的调用等汇编语言知识的有效运用。
本次课程设计以实现一个基本功能完善,界面友好,操作简便易行的计算器为最终目的。
通过对具有加减乘除基本功能的计算器的设计实现,学会使用汇编语言实现输入输出模块的设计,模块合理调用的设计,加减乘除运算的判断以及退出程序的判断的设计。
通过对各种指令的合理使用,熟悉并加深对各种指令的用法。
学会使用汇编语言设计各个功能模块。
当实现各个程序模块后,学会通过程序的调用最终实现一个具有基本计算功能的简单计算器。
1中文摘要实现一个简单计算器,要求编写一个程序,每运行一次可执行程序,可以实现数的加减乘除四则运算。
运算过程中的进位或是借位,选择用什么样的方式进行输出,如何实现清屏等也是要解决的问题。
设计当用户根据提示信息输入一个算式后,按下enter键或是‘=’符号键时,程序依据输入的算式进行计算,并将结果显示在屏幕上。
如果用户输入错误,则返回,提示信息让用户重新输入算式,当用户按下Q或q键时退出程序。
在各个子功能模块设计好的情况下,通过主题模块的合理调用,最终实现一个具有简单运算功能的计算关键字:计算器、四则运算、进位、错位、清屏目录1系统分析 -------------------------------------------------2系统总体设计----------------------------------------------3详细设计-------------------------------------------------- 4统测试 ---------------------------------------------------5软件使用说明书 ------------------------------------------- 设计总结----------------------------------------------------参考文献----------------------------------------------------致谢———————————————————————————————————31.系统分析本次汇编语言课程设计的最终目的是要实现一个简单计算器,要求编写一个程序,每运行一次可执行程序,可以实现数的加减乘除四则运算。
比如,十进制数的加减乘除四则运算。
我们曾经学习过两个具体数字进行加减法运算,但是对于简单计算器用汇编语言实现难点在于这两个要做运算的数是未知的,是由自己调用中断输入到屏幕上并要用程序存储起来的数,然后才能对这两个数进行运算,而且做的是加法运算、减法运算乘法运算还是除法运算也未可知,为此我们还要判断用户所输入的运算是四则运算中的哪一个运算。
此外,运算过程中的进位或是借位,选择用什么样的方式进行输出,如何实现清屏等也是要解决的问题。
第一步,我要解决的是输入时是用INT 21H的10号功能调用还是用INT 21H 的1号功能调用来进行输入。
若是用10号功能调用则我们进行多字符输入,可以将输入的字符都存储到一个数据区里面,并调用9号功能调用输出存进去的字符,这种输入和输出的方案是可行的。
我选择的是利用1号功能调用来输入,即把单个字符一个个的输入并存储到一个数据区里。
我们要做的是两个数的运算,先认定输入的格式为1234+5678=或者1111*2222=,当然如果输入不是这样的格式计算出来的结果就不一定是我们想要的结果了。
在存储的时候也是有选择的存储,当输入的并非格式里所要求的字符时则报错。
第二步,设计程序进行判断所输入的算式是做加法运算、减法运算、乘法运算还是除法运算,即判断输入的运算符是‘+’号、‘-’号、‘*’号、‘/’号中的哪一个,因为输入的格式固定了,所以只需要把存进数据区的第三个字符拿来与加减乘除四个运算符号进行比较,和哪一个运算符号一样就调用相对应的运算模块进行计算。
第三步,根据计算器程序所要实现的功能完成各个功能模块。
设计程序主体部分,根据主体部分所需的功能模块对各个子模块一一进行设计编写。
子模块中包含有:do_add加法运算模块,do_sub减法运算模块,do_mul乘法运算模块,do_div 除法运算模块,input输入模块等。
最后还要对这个简易计算器进行功能完善。
为了使程序符合我们使用者的操作习惯,设计当用户根据提示信息输入一个算式后,按下enter键或是‘=’符号键时,程序依据输入的算式进行计算,并将结果显示在屏幕上。
如果用户输入错误,则返回,提示信息让用户重新输入算式,当用户按下Q或q键时退出程序。
在各个子功能模块设计好的情况下,通过主题模块的合理调用,最终实现一个具有简单运算功能的计算52.系统总体设计73.详细设计B_P EQU BYTE PTRW_P EQU WORD PTRD_P EQU DWORD PTRCODE SEGMENTASSUME CS:CODE,DS:CODEORG 100H;主程序开始NEWSTAR:JMP STAREVENNUM1 DW 0,0NUM2 DW 0,0NUM3 DW 0,0JGV4 DW 0,0YSF LABEL WORDYSF1 DB 0YSF2 DB 0JUV DB 0UV DB 0;使DS:SI指向第一有效字符OVERS LABEL NEARCLDPUSH AXOVERS1:LODSBCMP AL,' 'JZ OVERS1CMP AL,9JZ OVERS1DEC SICMP AL,13POP AXRET;输出一个制表符TAB LABEL NEARMOV AL,9JMP SHORT DISP ;输出一个回车换行符CRLF LABEL NEARMOV AL,13CALL DISPMOV AL,10;显示一个字符DISP LABEL NEARPUSH AXPUSH DXMOV AH,2MOV DL,ALINT 21HPOP DXPOP AXRET;检查是否为运算符ISYSF LABEL NEARCLDLODSBCALL ISJJJZ ISYSF1CALL ISIIJZ ISYSF1DEC SI9ISYSF1:RET;检查是否是加减运算ISJJ LABEL NEARCMP AL,'+'JZ ISYSF1CMP AL,'-'RET;检查是否为乘除运算ISII LABEL NEARCMP AL,'*'JZ ISYSF1CMP AL,'/'JZ ISYSF1CMP AL,'\'RET;数据输出;CX=10 十进制;CX=16 十六进制DOUT LABEL NEARPUSH AXPUSH BXPUSH DXPUSH BPXOR BP,BP DOUT1:INC BPPUSH AXMOV AX,DXXOR DX,DXDIV CXMOV BX,AXPOP AXDIV CXPUSH DXMOV DX,BXOR BX,AXJNZ DOUT1DOUT2:POP AXADD AL,'0'CMP AL,'9'JBE DOUT3ADD AL,'A'-'9'-1 DOUT3:CALL DISPDEC BPJNZ DOUT2POP BPPOP DXPOP BXPOP AXRET;输入数据在DX:AX中返回;CX=0 数据为10进制;CX#0 数据为16进制DATE LABEL NEARPUSH BXPUSH BPPUSH DIXOR AX,AXXOR DX,DX11MOV DI,AXLODSBCMP AL,'0'JB DATE7CMP AL,'9'JA DATE6DATE2:AND AX,0FHSHL DI,1RCL DX,1MOV BX,DIMOV BP,DXSHL DI,1RCL DX,1SHL DI,1RCL DX,1JCXZ DATE3SHL DI,1RCL DX,1Jmp short DATE4 DATE3:ADD DI,BXADC DX,BPDATE4:ADD AX,DIADC DX,0JMP DATE1DATE5:ADD AL,9JMP DATE2JCXZ DATE7CMP AL,'A'JB DATE7CMP AL,'F'JBE DATE5CMP AL,'a'JB DATE7CMP AL,'f'JBE DATE5DATE7:MOV AX,DIDEC SIOR DI,DXPOP DIPOP BPPOP BXRET;数据1与数据2根据YSF1进行加减运算JSJJ LABEL NEARMOV AX,NUM2MOV DX,NUM2+2CMP YSF1,'+'JZ JSJJ1SUB NUM1,AXSBB NUM1+2,DXJMP SHORT JSJJ2 JSJJ1:ADD NUM1,AXADC NUM1+2,DX JSJJ2:13RET;数据1与数据2根据YSF1进行乘除运算JSII1 LABEL NEARMOV BX,OFFSET NUM1JMP SHORT JSII2_1 ;数据2与数据3根据YSF2进行乘除运算JSII2 LABEL NEARMOV BX,OFFSET NUM2 JSII2_1:DB 66HMOV AX,[BX]DB 66HMOV CX,[BX+4]CMP YSF2,'*'JNZ JSII2_2DB 66HIMUL CXJMP SHORT JSII2_3 JSII2_2:DB 66HCWDDB 66HIDIV CXCMP YSF2,'/'JZ JSII2_3DB 66HXCHG DX,AXJSII2_3:DB 66HMOV [BX],AXRET;显示结果XUJG LABEL NEARMOV AX,JGV4MOV DX,JGV4+2MOV CX,10CMP UV,10JZ XUJG0MOV CX,16XUJG0:TEST DX,8000HJZ XUJG1CMP UV,10JZ XUJG2CALL DOUTXUJG2:NOT AXNOT DXADD AX,1ADC DX,0PUSH AXCMP UV,10JZ XUJG3MOV AL,' 'CALL DISPMOV AL,'('CALL DISPXUJG3:MOV AL,'-'CALL DISPPOP AXCMP UV,1015JZ XUJG1CALL DOUTMOV AL,')'CALL DISPRETXUJG1:CALL DOUTRET;计算结果放入DX:AX中JSJG LABEL NEARCALL JSJJMOV AX,NUM1MOV DX,NUM1+2RET;从DS:SI处取一个数据LOADATE LABEL NEARLODSBCMP AL,'('JZ LOADATE1DEC SIPUSH CXXOR CX,CXCMP UV,10JZ LOADATE0INC CX ;取16进制数LOADATE0:CALL DATE ;取数据放入DX:AX中POP CXRETLOADATE1:PUSH NUM1 ;保存数据1数据2及运算符PUSH NUM1+2PUSH NUM2PUSH NUM2+2PUSH YSFINC JUVMOV JGV4,0 ;结果值清零MOV JGV4+2,0;进行四则运算SZYS LABEL NEARCALL ISYSF ;首字符是运算符?JZ SZYS2CALL LOADATE ;不是,取数并保存MOV NUM1,AXMOV NUM1+2,DXSZYS1:XOR AX,AX ;数据2清零MOV NUM2,AXMOV NUM2+2,AXCALL ISYSF ;下个是运算符?JZ SZYS3JNZ SZYS6SZYS2:PUSH AXMOV AX,JGV4 ;将结果作为数据1MOV NUM1,AXMOV AX,JGV4+2MOV NUM1+2,AXPOP AXSZYS3:MOV YSF1,ALMOV YSF2,AL17CALL ISJJ ;是加减运算转JZ SZYS4CALL LOADATE ;取数据2MOV NUM2,AXMOV NUM2+2,DXCALL JSII1 ;数据1与数据2根据YSF1进行乘除运算JMP SZYS1 ; 结果保存在数据1中SZYS4:CALL LOADATE ;取数据2并保存MOV NUM2,AXMOV NUM2+2,DXSZYS4_1:CALL ISYSFJNZ SZYS6CALL ISJJ ;运算符2是加减运算?JNZ SZYS5 ;不是转PUSH AXCALL JSJJ ;数据1与数据2根据YSF1进行加减运算POP AX ; 结果保存在数据1中MOV YSF1,AL ;保存新的运算符JMP SZYS4SZYS5:MOV YSF2,AL ;保存运算符2CALL LOADATE ;取数据3MOV NUM3,AXMOV NUM3+2,DXCALL JSII2 ;数据2与数据3根据YSF2进行乘除运算JMP SZYS4_1 ; 结果保存在数据2中SZYS6:MOV CL,ALCMP AL,13JNZ SZYS9SZYS7:CALL JSJGCMP JUV,0JZ SZYS8DEC JUVPOP YSFPOP NUM2+2POP NUM2POP NUM1+2POP NUM1RETSZYS8:CMP CL,')'JZ SZYS10MOV JGV4,AXMOV JGV4+2,DXJNZ SZYS12SZYS9:CMP AL,')'JNZ SZYS11INC SIJMP SZYS7SZYS10:MOV NUM1,AXMOV NUM1+2,DXJMP SZYS1SZYS11:19STCRETSZYS12:CLCRET;数制处理UVIL LABEL NEARPUSH SI UVIL1:LODSBCMP AL,' 'JZ UVIL2CMP AL,9JZ UVIL2CMP AL,13JZ UVIL4JNZ UVIL1 UVIL2:MOV BX,SICALL OVERSJZ UVIL3LODSWCALL OVERSPOP SIJNZ SZYS11CMP AX,'01'JNZ SZYS11PUSH SIMOV UV,10 UVIL3:MOV AL,13MOV [BX-1],AL UVIL4:POP SICLCRET;预置结果YVJG LABEL NEARMOV AH,52HINT 21HMOV AX,ES:[BX-2]MOV DS,AXMOV AX,DS:[0CH]MOV CS:JGV4,AXMOV AX,DS:[0EH]MOV CS:JGV4+2,AXPUSH CSPOP DSPUSH CSPOP ESRET;保存结果BCJG LABEL NEARMOV AH,52HINT 21HMOV AX,ES:[BX-2]MOV DS,AXMOV AX,CS:JGV4MOV DS:[0CH],AXMOV AX,CS:JGV4+2MOV DS:[0EH],AXPUSH CS21POP DSPUSH CSPOP ESRETSTAR:MOV SI,81HCLDCALL OVERSJNZ STAR1STAR0:MOV DX,OFFSET MESS1JMP STAR4STAR1:CALL YVJGCALL UVILJB STAR0MOV SAVESP,SPCALL SZYSMOV SP,SAVESPMOV DX,OFFSET MESS2JB STAR4CALL CRLFCALL XUJGCALL BCJGMOV DX,OFFSET MESS3 STAR4:MOV AH,9INT 21HINT 20HSAVESP DW 0MESS1 DB 13,10,' Syntax:',13,10DB ' JS <Expression> [10]',13,10,'$' MESS2 DB 'Error in expression !$'MESS3 DB 13,10,'$'CODE ENDSEND NEWSTAR234.系统测试4.1 运行界面分析将源程序输入编辑程序中,检查无误后经汇编、连接后装入系统运行界面如图4-1所示:图4-1 运行界面程序的运行界面显示成功,屏幕上显示“input a suanshi(input q exit):”提示用户输入一个算式。