slipegg / assembly-language

同济大学汇编原理课程,用汇编语言实现一般数据的四则运算,运行平台在DOSBox 0.74软件下

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

assembly-language

本项目为同济大学汇编原理课程的大作业。

(一)设计题目:

用汇编语言实现一般数据的四则运算,运行平台在DOSBox 0.74软件下。

(二)设计说明

1.功能

该程序完成了基础的四则运算,对于运算符号出现的次数没有限制,但是只能出现+ - * /,不能出现()。 对于运算的数据,不仅仅局限于个位,可以是整数,也可以是小数,只要是数据小于655.35,以及运算过程中产生的数据都小于655.35,就可以正常运算。但注意小数会被截断,只有小数位的前2位会被取用,最后的结果保留一位小数,并对最后一位四舍五入。

2.子程序

设计了如下的子程序:

image

子程序之间没有嵌套调用,都是一路顺序执行。

3.子程序功能介绍

  • WRITE :用来获得一个从键盘输入的表达式,放入EXPRESSION中
  • CHANGETONUM :获得表达式EXPRESSION中的数值,并将单独的数值转化为数据放入NUMBER中,例如EXPRESSION是”14+12.34*6-100/4”,那么最后放入NUMBER的是1400,1234,600,10000,400。都是讲其扩大了100倍,然后从字符串转化为数值
  • GETOPERATOR :获得表达式EXPRESSION中的运算符,放入OPERATOR中, ,例如EXPRESSION是”14+12.34*6-100/4”,那么最后放入OPERATOR的是+,*,-,/这几个字符
  • FIRSTOPERATE :进行第一步运算,将EXPRESSION中的所有的乘除运算都运算完,把后续需要加减的数值都放入ADDSUBNUM中,例如EXPRESSION是”14+12.34*6-100/4”,那么最后经过运算,放入ADDSUB中的是1400,7404(1234*6的结果),2500.
  • ADDSUBALL :进行第二步运算,将ADDSUBNUM的数按顺序进行加减运算,最后讲运算结果放入ANSWER中,如上例中的ADDSUBNUM中的值,最后放入ANSWER的值是6304
  • CALL PRINTANSWER ;根据ANSWER中的值来书写答案,如上的ANSWER的值,那么最后输出的就是63.0

image

4.程序框图:

image

5.子程序:

WRITE: 用来获得一个从键盘输入的表达式,放入EXPRESSION中,并判断是否输入了错误的字符

image

CHANGETONUM:获得表达式中的数值,放入NUMBER中

image

GETOPERATOR:获得表达式中的运算符,放入OPERATOR中

image

FIRSTOPERATE:进行第一步运算,将所有的乘除运算都运算完,把后续需要加减的数值都放入ADDSUBNUM中

image

ADDSUBALL:进行第二步运算,将ADDSUBNUM的数按顺序进行加减运算

image

PRINTANSWER:书写答案,注意一开始要进行四舍五入的判断

image

三.调试说明

1.遇到的问题:

1)在将表达式中的数据单独拿出来的时候,因为考虑到小数,所以需要将他们扩大100倍,然后出现了问题,因为如果是整数的话就不会遇见’.’,就不会继续*10,或者遇到只有一位的小数,也会少乘一个10 解决方法:用CX专门记录遇到小数点后,*10 的次数,如果没有遇到’.’就是0,如果遇到小数点后只有一个数字,这样就可以知道自己少乘的10的次数,然后把它补足

2)关于对表达式循环操作何时结束的问题,原本是打算利用它有一个位数是专门记录后面的输入有多少字节,但是有时候又不方便统计操作了多少字符了 解决方法:注意到最后还有一个0DH,即回车键,然后就可以判断指向的字符是不是0DH,如果是,就说明来到了表达式的尽头,就可以结束循环了

3)将运算符单独放入内存中后,再次使用的时候,如何知道何时将运算符操作完了 解决方法:最后将0DH也放入存放运算符的内存中,用它来标记结尾

4)数扩大了一百倍之后,如何进行乘除法 解决方法:在进行乘法时将一个乘数再缩小100倍,在除法时,将除数缩小100倍,这样就可以近似得到正常结果,但是如果不幸的进行缩小的这几个数是小数,那么就会舍弃掉小数位的数字,最后导致结果有较大偏差,所以还是不建议使用小数的乘除法,如果要用,第二个乘数和除数应该为整数

5)在先进行乘除法的操作的时候,如何将有连续乘除法的数据正常运算完 解决方法:在检测到下一个运算符是乘除号时,将第一次的乘除法的结果放入一个寄存器中,然后用这个寄存器继续和后面的数进行乘除运算,直到遇到的运算符不是乘除号或者遇到0DH,就结束,然后将这个寄存器里的数据放入内存中储存起来。

6)输出答案中如何避免前面多余的0的输出 解决方法:在判断到取出的余数是0的时候,再多进行一次判断,即用SI来统计前面有没有输出过字符,如果发现没有,还是0,那么就不输出这个字符,如果发现有输出了,那么这个0也还是要输出

7)如何确保能够正常四舍五入 解决方法:在运算过程和准备过程中都是采用2位小数的运算,最后结果看最后第二位小数,然后来决定第一位小数要不要+1

8)调试过程中出现过程序在条件转移后,到了其他地方去: 解决方法:发现是因为跳转位置的名称有重名,然后就跳到了最上面的那里去了,改名就好了

9)调试过程中发现子程序返回后没有回到原来主程序的位置 解决方法:发现是因为子程序动用了SS寄存器,导致最后返回错误,所以对于缺寄存器的情况,选择在内存中开辟2个变量用来运算 程序设计技巧: 本程序看起来不难,但是对应于汇编它极度缺少运算自由度的情况下,还是有点麻烦的,我采取的方法是分步,多分步。分别将数值、操作符提出来,然后运行第一步,乘除法,然后进行加减,然后输出结果。这里面每一步在实行的时候都要保障之前是正确的,不然错误累积起来就不知道如何修改了,所以我都是每次都添加完了一些步骤后,就debug程序,查看里面的结果是不是符合自己的预想,如果不对,就进行查看修改,我认为千万不能一次性加入太多代码,然后再debug这样真的会焦头烂额,而且有时候有一些微小的bug是不容易察觉的,这样一步一步的走来,就可以得到结果了。而这在分步的时候一定要在心中有个蓝图,知道自己要几步才能完成这个程序,每次完成后的功能如何,在后面修改时候的兼容性如何。像我在设计的时候,一开始是没有考虑小数的,在debug的时候,都是使用整除,因为我当时想的是只要整数的运算能解决,那么小数仅仅只需要将运算数据扩大100倍就好了,即只需要修改好前面录入的数据的值,就可以很好的兼容了,所以在最后再加入小数的运算功能时,也能够很好的运算,没有出现太大的问题

2.运行结果: 运算准确性: image

image

image

运算时第二个乘数和除数如果为小数会舍弃小数位进行计算,导致有偏差,如第一第二个式子,但是如果在第一个乘数和被除数就不会有偏差了,如第三第四个式子

image

运算的临界性最大值是655.35:

image

不支持负数:

image

可以四舍五入:

image

只截取小数点后两位:

image

四舍五入之后能进行进位处理:

image

输入错误会有提示,然后再要求重新输入

image

输入除以0也属于运算式子错误

image

四.使用说明

1.该程序是在WIN10系统下完成测验的,在DOSBox 0.74软件下,在80x86指令系统下正常运行和debug 2.打开DOSBox 0.74,将程序编译,即输入masm 程序名,然后对跳出的指令一直回车,然后再link 程序名,对跳出的指令一直回车,然后就得到了exe文件了,然后再输入程序名,就可以运行这个exe文件了,然后就输入合法的要计算的表达式,就会跳出结果了,如果要调试就输入debug 程序名.exe,然后就可以进入调试。 3.输入的信息必须是正常的表达式,数据可以是整数也可以是小数,+-*/都可以使用,但是不能使用(),运算的中间结果和最后的结果都不能大于655.35,不然会出现错误答案,运算的中间结果和最后的结果也不能是负数,不然也会出错。运算时第二个乘数和除数如果为小数会舍弃小数位进行计算,导致有偏差,但是如果在第一个乘数和被除数就不会有偏差了 4.出错信息:当输入了除数字和+-*/外的其他字符或者除法后面跟了个0的时候,就会检测出输入有误,然后弹出“The expression has error!”,然后再次弹出提示,请求再次输入

五.心得体会

程序看起来不难,但是对应于汇编它极度缺少运算自由度的情况下,还是有点麻烦的,我采取的方法是分步,多分步。分别将数值、操作符提出来,然后运行第一步,乘除法,然后进行加减,然后输出结果。这里面每一步在实行的时候都要保障之前是正确的,不然错误累积起来就不知道如何修改了,所以我都是每次都添加完了一些步骤后,就debug程序,查看里面的结果是不是符合自己的预想,如果不对,就进行查看修改,我认为千万不能一次性加入太多代码,然后再debug这样真的会焦头烂额,而且有时候有一些微小的bug是不容易察觉的,这样一步一步的走来,就可以得到结果了。而这在分步的时候一定要在心中有个蓝图,知道自己要几步才能完成这个程序,每次完成后的功能如何,在后面修改时候的兼容性如何。像我在设计的时候,一开始是没有考虑小数的,在debug的时候,都是使用整除,因为我当时想的是只要整数的运算能解决,那么小数仅仅只需要将运算数据扩大100倍就好了,即只需要修改好前面录入的数据的值,就可以很好的兼容了,所以最后再加入小数的运算功能时,也能够很好的运算,没有出现太大的问题

About

同济大学汇编原理课程,用汇编语言实现一般数据的四则运算,运行平台在DOSBox 0.74软件下


Languages

Language:Assembly 100.0%