1. 设计目标
运用汇编语言,制作一个计算的程序,实现简单计算器的一般功能,能够在DOS界面下进行简单的加、减、乘、除的简单计算。程序应有操作提示、输入和输出。自动闪烁光标,并提示输入信息。输入正确的数值等符号后可以进行正确的运算,程序计算其结果值并输出。程序无需查错功能,所输入的都是正确的四则运算表达式,并且表达式中运算分量均为无正负号整数,运算符为 +-*/,最后结果以十进制数表示。且程序主界面需为一个由‘*’组成边框的矩形窗口。
汇编语言直接同计算机的底层软件甚至硬件进行交互,它具有如下一些优点:能够直接访问与硬件相关的存储器或I/O端口;能够不受编译器的限制,对生成的二进制代码进行完全的控制;能够对关键代码进行更准确的控制;能够根据特定的应用对代码做最佳的优化,提高运行速度;能够最大限度地发挥硬件的功能。
2. 软件设计
2.1程序设计的基本思想
主模块:首先提供一个主界面,提示用户按要求输入具体的数据和所要进行的操作,输入完毕后给出结果。如果输入过程中发现非法输入,则立即给与提示,程序自动刷新界面,提示继续输入。计算显示完毕后,按提示选择是否要继续计算,不选择继续则结束。对屏幕上输入字符串的接受,为INPUT语句段,见源代码,主要是将数字和运算符分开存放。MATCH子程序,子程序内有三次跳转,将运算符选择正确的语句进行计算。由于操作符只有+-*/,没有涉及到括号,不用考虑括号的匹配问题。流程图如下:
1 主模块流程图
子模块:完成对数据的进一步加工处理,转换格式并得出结果。首先根据输入调用对应的“+”“-”“*”“/”四个函数模块,这是本程序的核心模块,其他部分的一些小模块都是为这几个模块服务的,大致的流程图如下图2
2 子模块流程图
2.2代码
STACK  SEGMENT  STACK
  DB  200 DUP(0)
STACK  ENDS
DATA SEGMENT
  OPS    DB ?
  OPD    DB ?
  OPER    DB ?
  TIT    DB'***********************************' ,0DH,0AH
          DB'*            Made By              *' ,0DH,0AH  ;0DH代表回车         
          DB'*  Tong Xin Ji Suan Qi Xiao Zu  *' ,0DH,0AH  ;0AH代表换行         
          DB'* Chang qian  Zuo xin  Wang xin *' ,0DH,0AH
          DB'*  Wang da yong  Tang kuan long  *' ,0DH,0AH
          DB'*            + - *  /            *' ,0DH,0AH
          DB'*    Y,y:continue    N,n:quit    *' ,0DH,0AH
          DB'*************Calculate*************$',0DH,0AH
  Tip1    DB 'Input the first  operator (0---9):$',0DH,0AH
  Tip2    DB 'Please input the oper (+,- ,*,/) :$',0DH,0AH
  Error  DB 'Error! Plese input the oper again:$',0DH,0AH
  Tip3    DB 'Input the second operator (0---9):$',0DH,0AH
  Result  DB '--------------->the  result  is:$',0DH,0AH   
  Quit    DB 'Choose repeat or quit? (Y/y/N/n) :$',0DH,0AH
  Tsave  DB ?
DATA  ENDS
CODE SEGMENT
  ASSUME  CS: CODE,DS:DATA,SS:STACK
START:         
    MOV  AX,DATA                    ;初始化 DS:DX
    MOV  DS,AX
Remain: 
    MOV  BL,0                      ;Oper(恢复)初始状态
    MOV  OPS,BL
    MOV  OPER,BL
    MOV  OPD,BL
    LEA  SI,OPS                    ;OPS的偏移地址送给SI
    LEA  DI,OPD                    ;OPD的偏移地址送给DI
    CALL  Enter
    LEA  DX,TIT                   
    MOV  AH,9 
    INT  21H
    CALL  Input1                    ;调用输入第一个操作数                   
    CALL  Operat                    ;调用输入操作符
    CALL  Input2                      ;调用输入第二个操作数
    CALL  Calculate                  ;调用计算方法
    CALL  StrQuit                    ;调用判断程序再次执行
    MOV  AH,1
    INT  21H
    CMP  AL,'Y'
    JE    Remain
    CMP  AL,'y'                    ;汇编语言如何编程选择Y返回Remain继续执行
    JE    Remain
    CMP  AL,'N'
    JE    EXIT                     
    CMP  AL,'n'
    JE    EXIT 
EXIT:MOV  AH,4CH                    ;若不是Y则结束
    INT  21H   
;输入操作数子程序---------------------------------------------------------
Input1 PROC NEAR
    CALL  Enter
    LEA  DX,Tip1                    ;输入第一个操作数提示----------
    MOV  AH,9 
    INT  21H                        ;十进制输入提示
BCDin1: 
    MOV  AH,1
    INT  21H
    CMP  AL,0DH
    JE    EndBCDin1                  ;等于回车则返回继续输入运算符
    CMP  AL,30H                         
    JB    BCDin1                    ; <0时转exitinD 退出
    CMP  AL,39H
    JA    BCDin1                    ; >9时转exitinD 退出
    AND  AL,0FH                    ;清除高位   
    MOV  [SI],AL
    INC  SI
    LOOP  BCDin1
EndBCDin1: 
    CALL  Enter                      ;回车换行
    RET
Input1  ENDP
Input2 PROC NEAR
    CALL  Enter
    LEA  DX,Tip3                  ;输入第二个操作数提示----------
    MOV  AH,9 
    INT  21H                      ;十进制输入提示
BCDin2: 
    MOV  AH,1
    INT  21H
    CMP  AL,0DH
    JE    EndBCDin2                  ;等于回车则返回继续输入运算符
    CMP  AL,30H                         
    JB    BCDin1                    ; <0时转exitinD 退出
    CMP  AL,39H
    JA    BCDin1                    ; >9时转exitinD 退出
    AND  AL,0FH                    ;清除高位   
    MOV  [SI],AL
    INC  SI
    LOOP  BCDin2
EndBCDin2: 
    CALL  Enter                      ;回车换行
    RET
Input2  ENDP
;输入操作符子程序-------------------------------------------------------
Operat  PROC NEAR
ReOperat:
    CALL  Enter
    LEA  DX,Tip2                ;输入操作符提示
    MOV  AH,9 
    INT  21H             
    MOV  AH,1
    INT  21H
    CMP  AL,'+'
    JE    OperSave              ;若为"+",则存在oper
    CMP  AL,'-'
    JE    OperSave
    CMP  AL,'*'
    JE    OperSave
    CMP  AL,'/'
    JE    OperSave
    JMP  OperError
OperError:
    CALL  Enter
    LEA  DX,Error                ;输入操作符的错误提示
    MOV  AH,9 
    INT  21H
    JMP  ReOperat
OperSave:
    MOV  OPER,AL
    RET
Operat ENDP
;计算方法子程序-----------------------------------------------------
Calculate PROC NEAR
    CALL  Enter                      ;回车换行
    MOV  BL,OPER
    CMP  BL,'+'
    JZ    ADCProc                  ;若为加法,则转到adcProc
    CMP  BL,'-'
    JZ    SUBProc
    CMP  BL,'*'
    JZ    MULProc
    CMP  BL,'/'
    JZ    DIVProc
ADCProc:
    CALL  StrResult                ;加法
    MOV  AL,OPS
    ADC  AL,OPD
    CALL  Displ
    JMP  endCalculate
SUBProc:                            ;减法 
    CALL  StrResult 
    MOV  AL,OPS
    SUB  AL,OPD
    CALL  Displ
    JMP  endCalculate
MULProc:                            ;乘法
    CALL  StrResult 
    MOV  AL,OPD
    MUL  OPS
    CALL  Displ
    JMP  endCalculate
DIVProc:                            ;除法
    CALL  StrResult 
    MOV  AH,0
    MOV  AL,OPS
    DIV  OPD
    CALL  Displ
    JMP  endCalculate
endCalculate:
    RET
Calculate  ENDP
Displ  PROC NEAR
    MOV  Tsave,AL
    MOV  AH,0
    MOV  AL,Tsave
    MOV  BL,100
    DIV  BL                        ;除以100
    CALL  Output                    ;显示百位数
    MOV  AL,AH
    MOV  AH,0
    MOV  BL,10
    DIV  BL                        ;除以10
    CALL  Output                    ;显示十位数
    MOV  AL,AH
    CALL  Output                    ;显示个位数
    RET
Displ  ENDP
StrResult  PROC NEAR
    LEA  DX,Result
    MOV  AH,9 
    INT  21H
    RET 
StrResult  ENDP
Output PROC  NEAR                  ;十进制输出
    PUSH  AX
    ADD  AL,30H                ;AL中的十进制数变成ASCII
    MOV  DL,AL
    MOV  AH,2
    INT  21H
    POP  AX
    RET
Output ENDP
;回车换行子程序--------------------------------------------------
Enter  PROC NEAR           
    MOV  DL,0AH
    MOV  AH,2
    INT  21H
    MOV  DL,0DH
    MOV  AH,2
    INT  21H   
    RET
Enter  ENDP
;判断程序再次执行子程序-----------------------------------------------
StrQuit  PROC NEAR 
    CALL  Enter                      ;回车换行         
    LEA  DX,Quit 
    MOV  AH,9 
    INT  21H
    RET
StrQuit    ENDP
CODE ENDS
    END  START
3. 系统调试
3.1测试目标
(1)在屏幕上显示一个由‘*’组成边框的矩形窗口;
(2)自动闪烁光标,并提示输入信息;
(3)能够完成单项表达式的输入、显示和运算;
(4)编制并调试出程序。
3.2测试方法及结果
    单击开始,启动运行,输入cmd,启动命令提示符,进入DOS系统。如下图:
       
3 启动命令提示符
源程序名存为qian.asm,dos下进入F盘,再cd masm进入masm文件夹,再键入masm qianqian是源程序文件名)提示是否更改文件名(不改直接回车),系统会提示是否生成.lst文件和.crf文件(直接回车跳过),这样就生成了qian.obj 键入link qianqian是源程序文件名),提示是否更改文件名(不改直接回车)提示是否生成.map.lib文件(直接回车),这样就生成了,再在DOS下键入qian(源程序文件名)就进入程序执行。如图4
4 执行方法
在计算器内,输入数字测试本程序的正确与否。
按照提示输入第一个十进制数,如“6”,回车。下一步,会提示请输入运算符,如加“+”,回车。最后一步,输入第二个十进制数,如“3”,回车。则显示出其运算结果。如下图5所示:
5 实现加法运算
同上,可实现减法、乘法、除法运算,分别如图6,图7,图所示8
6 实现减法运算
7 实现乘法运算
8 实现除法运算
运算完毕后,会提示是否继续下一个运算,输入“Y”则继续运算,并返回主界面,输入“N”则结束程序。
当运算符输入不合法时,则会提示重新输入运算符,如下图9
9 错误提示
4. 总结
设计的这个程序主要是进行表达式的四则运算,由于操作符只有+-*/,没有涉及到括号,因此设计起来要容易一点,不用考虑括号的匹配问题。另外,跳转时汇编语言的一大难点,再编程之前最好要画出流程图,这样在写跳转时不容易出错,且不会出现重复操作语句段。输入部分看似简单,实际要考虑到很多细。比如一开始没想到存入的数据可能会符号存进内存后的相同;如何判段存数算法应该结束,对应的存入数和符号。
编写的五个子程序经编译、链接后,没有发现错误,可设计出的计算器程序出现一些不足,如本计算器只能进行一位十进制数的计算,也很少在计算的优先级,进制转化之间下功夫,致使计算器运算能力不足。还有本程序只能判断输入的运算符的合法性,不能判断输入的十进制数的正确与否,即使错误,也显示提示下一步的操作。
参考文献
[1] 詹仕华. 汇编语言程序设计[M]. 北京: 中国电力出版社, 2008.273-102
[2] 宋彩莉, 王禾. 汇编语言程序设计学习指导[M]. 西安: 西安交通大学出版社, 2008.245-87
[3] 李敬兆, 陈子旭. 汇编语言程序设计[M].合肥: 中国科学技术大学出版社, 2008.9173-197
[4] 钱晓捷, 周玲. 新汇编语言程序设计[M]. 北京: 电子工业出版社, 2006.3101-120
[5] 周佩玲, 彭虎, 傅忠谦. 微机原理与借口技术[M]. 北京: 电子工业出版社, 2007.1113-141
[6] 马春燕. 微机原理与接口技术(基于32位机)实验与学习辅导[M]. 北京: 电子工业出版社, 2007.123-70
[7] 何小海, 严华. 微机原理与借口技术[M]. 北京:科学出版社, 2006.7143-180
[8] 王爽, 胡雄. 汇编语言[M]. 北京: 清华大学出版社, 2009.929-70
[9] 曹加恒, 谢子殿. 新一代汇编语言课程设计[M]. 北京: 高等教育出版社, 2006.3113-138
[10] 杨路明. 汇编语言程序设计[M]. 长沙: 中南大学出版社, 2008.5173-203

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。