微机设计的报告.docx
- 文档编号:26689284
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:16
- 大小:23.55KB
微机设计的报告.docx
《微机设计的报告.docx》由会员分享,可在线阅读,更多相关《微机设计的报告.docx(16页珍藏版)》请在冰豆网上搜索。
微机设计的报告
仲恺农业工程学院
《计算器的汇编语言实现》
班级:
通信工程
学号:
姓名:
设计日期:
2011/3/21—2011/3/25
教师评价:
数字计算器的汇编语言实现
一、课程设计名称:
计算器的汇编语言实现
二、实验目的:
1、熟悉计算机汇编语言
2、学会编辑专用的计算器汇编程序
3、学会用理论与实验相结合的思想。
三、设计的内容:
设计一个能输入运算算式,按回车后显示计算结果的计算器。
要求:
1、实现正整数的四则混合运算,例如:
1+2x3-4
2、实现有括号的四则混合运算,例如:
(1+2)x3–4
3、实现多括号嵌套,例如:
((1+2)x3)-4,或实现负整数括号不嵌套的四则混合运算,例如:
(-1+2)x(-3)-4
四、设计的代码:
;-----------------定义数据段--------------
datasegment
number1DW100dup('$');定义缓冲区
number2DW100dup('$')
number3DW100dup('$')
resultDW0;初始化为零
c0DW0
c1DW0
c2dw0;求补时用
c3dw0
clc1DW0
clc2DW0
TableDW10000,1000,100,10,1;定义输出时要用到的除数
welcDB'********************************',13,10,13,10;定义欢迎词
DB'copyrightbyHuangBaiCai',13,10,13,10
DB'Pleaseenteryourformula',13,10,13,10
DB'********************************',13,10,13,10,13,10,'$'
error1DB'Error:
yourinputisincorrect!
pleaseenteragain.',13,10,'$'
dataends
;----------------------数据段定义完毕-------------------------------
;----------------------定义代码段-----------------------------------
codesegment
assumecs:
code,ds:
data
start:
movax,data
movds,ax
;-------------------------主函数定义--------------------------------
mainprocfar
leadx,welc;以下三句在界面中显示欢迎词
movah,09h
int21h
start1:
movbx,-1;是一个标志
movsi,0;指针置零
movdi,0;指针置零
movcx,0;
movc0,0;
movc1,0;标志作用,是否处理过数字
callwrite;调用等式转换子程序
callloopcount;调用括号优先级的子程序
calloutput;调用输出最终结果的子程序
exit:
movah,4ch;回DOS系统
int21h
mainendp
;-------------------主函数在此结束----------------------------------
;-------------------等式转换write子程序----------------------------
writeprocnear
startw:
movah,1
int21h;接收单字符输入的中断,放入AL
movah,0;清零AH
cmpal,1bh;'ESC'
jzexit;当输入ESC时跳到exit标号处
cmpal,2ah;'*'
jzmemory
cmpal,2fh;'/'
jzmemory
cmpal,2bh;'+'
jzmemory
cmpal,2dh;'-'
jzmemory
cmpal,29h;')'
jzmemory
cmpal,28h;'('
jzmemory
cmpal,3dh;'='
jzequal
subal,30h;除上述情况外,ASCCI码小于30H或大于39H的都判断为错误
cmpal,0;因为零的ASCII码为30H,所以比30H小的判断为错误
jlerror
cmpal,9;即比39H大的也判断为错误
jaerror
jmparithmetic;当输入为数字,而不是以下符号时,跳转到arithmetic标号处
;--------------------------------------
error:
leadx,error1;取error1的偏移地址
movah,9
int21h;显示ERROR1的内容
jmpstart1;跳回去准备继续输入
;-----------处理数字,bx不等于-1---------
arithmetic:
;
cmpc1,0;如果前面一个是运算符,须将BX清零。
如果前面是一个数字,则要将当前数字与前面数字合写
jearithmetic1;不跳转,ain1的入口1,,此时bx为上次数字的值;跳转时,ain1的入口2,此时bx会被清零
ain1:
movc0,ax;将输入的内容放到C0中
addc1,1;C1置1,C1是一个标志,操作完数字后,它为被置1,操作符号时它为0,
movax,bx;将bx赋给ax,
movcx,10;
mulcx;无符号乘,和前面一行一起实现将ax乘以10倍,即个位变成十位,十位变成百位
addax,c0;与前面数字合写
movbx,ax;将合写后的数字放在BX中,如果下次输入还是数字的话,继续合写;如果是符号,则与符号分别被存储。
jmpstartw
arithmetic1:
movbx,0;将标志BX清零,等待存储数字
jmpain1;ain1的入口2
;----------------存储符号或数字-----------------------
memory:
cmpbx,-1;倘若上一次操作没有处理过数字的话,直接存储;倘若上一次操作为处理数字,则先存储数字,然后再存储符号
jememorylp
movnumber1[si],bx;存储数字
addsi,2
movnumber1[si],ax;存储符号
movbx,-1;bx是一个寄存器,在这里作为一个标志使用,也作为存储作用。
处理数字后,BX不是-1;没处理过数字的话为-1
movc1,0;标志,表示这一次操作为处理符号,而不是数字
addsi,2
jmpstartw
memorylp:
movnumber1[si],ax;此时为上一次不是处理数字的情况,直接存储符号位
addsi,2
jmpstartw
;------------------当输入等号时----------------------
equal:
cmpbx,-1
jeequallp
movnumber1[si],bx;与前面MEMORY类似,如果上一次操作为数字,则先存储数字,在存储符号。
addsi,2
movnumber1[si],ax
jmpendw
equallp:
movnumber1[si],ax
jmpendw
endw:
RET
writeENDP
;------------------等式转换write子程序在此结束----------------------
;-------------------括号优先级loopcount子程序------------------------
loopcountprocnear
startlp:
movbp,0;初始化
movdi,0
movbx,0
movc0,0
movc1,0
movclc2,0
movsi,0
startl:
;指针SI从零开始,寻找右括号,找到后跳到rsee寻找左括号
movax,number1[si]
cmpax,29h;右括号)
jersee
addsi,2
cmpax,3dh;若遇到等号,则表示已经处理完所有的括号
jelastl;跳到最后的无括号运算
jmpstartl
rsee:
;寻找左括号
subsi,2;指针SI减2
movax,number1[si]
cmpax,28h;左括号(
jerwrite
jmprsee
rwrite:
;当一对最近的括号找到后,将SI放到CLC2,di置零
movclc2,si;存取左括号的偏移地址,因为等一下进行计算结果取代括号时,要用到
movdi,0
rwrite1:
;将括号中的内容复制到num2中,等待运算
addsi,2
movax,number1[si];将左括号右边的第一个内容放在ax
movnumber2[di],ax;即与上句一起实现将左括号右边的第一个内容放到number2的第一个空间
cmpax,29h;右括号)
jercount;遇到右括号就开始计算,这个NUMBER2中存在着右括号
adddi,2
jmprwrite1;存取括号右边的第二个内容放到number2的第二个空间
rcount:
movclc1,si;保存右括号的偏移地址,等一下计算出结果后,进行覆盖时要用到。
callfra;调用四则基本运算子程序
;----------------将结果覆盖左括号-----------------------
movdi,clc2
movax,result
movnumber1[di],ax;将计算结果覆盖左括号
;------右括号右边的内容往前移,覆盖之前计算式子及右括号位置-----
movsi,clc1
rcount1:
addsi,2;右括号右边的第一个位置,然后不断右移
adddi,2;左括号右边的第一个位置
movax,number1[si];将右括号右边的内容放到AX中
movnumber1[di],ax;和上一句一起实现将右括号右边的内容覆盖左括号左边的内容
cmpax,3dh
jestartlp
jmprcount1;不断循环,将右括号右边的内容往前移,直到将等号往前移(完成覆盖),跳回去寻找下一对括号
;-----------------------------------------------
lastl:
;所有的括号处理完毕,将指针SI清零
movsi,0
lastll:
;将number1中的内容转移到number2中,因为前面处理括号后number1有更新,其实这时number1中括号已全部处理完,所有的括号都已被数字替代。
movax,number1[si]
movnumber2[si],ax
addsi,2
cmpax,3dh
jeendl
jmplastll
;-------------------------------------------------
endl:
callfra;调用四则基本运算子程序
ret
loopcountendp
;-----------------括号优先级loopcount子函数在此结束------------------
;----------------计算四则基本运算(无括号)fra子程序-----------------
fraprocnear
movax,number2;直接寻址方式,将NUMBER2的偏移地址+DS值所指向的内容放到ax中,等同于movax,number2[0]
movnumber3,ax;和上一句实现将NUMBER2中的首内容放到number3的首内容,等同于movnumber3[0],ax
movdi,2;
movsi,2;直接寻找符号
;-----------------先乘除后加减-------------
int1:
movbx,number2[si];将要计算的第二个内容即运算符号位放到BX中
cmpbl,2ah;'*'判断运算符号,选择相应的运算
jemull
cmpbl,2fh;'/'
jedivv
cmpbl,3dh;'='
jechubu
cmpbl,29h;')';NUMBER2中存在右括号
jechubu
cmpbl,2bh;'+'
jein_fuzhi
cmpbl,2dh;'-'
jein_fuzhi
;--------------------------------
int2:
movnumber3[di],bx;存取加减符号
adddi,2
addsi,2
movax,number2[si]
movnumber3[di],ax;存取加减号右边的数
adddi,2
addsi,2
jmpint1
;------------------------------
in_fuzhi:
subdi,2;
movnumber3[di],ax;把加减符号左边的数放到number3中
adddi,2;回到加减符号处
jmpint2
;------------------------------
mull:
addsi,2
movbx,number2[si]
mulbx;无符号相乘,ax已存放了NUMBER2中的首内容,即符号左边的数,结果放在ax中,刚好可以在下一次判断时存取到number3中
addsi,2;即,如果下一个符号是乘,则AX与符号右边数相乘,如果下一个符号是加减,则存取到NUMBER3中
jmpint1;跳回去继续判断
divv:
addsi,2
movbx,number2[si];符号右边的数放到bx中
divbx;无符号相除,ax已存放了NUMBER2中的首内容,即符号左边的数,结果放在ax中
addsi,2
jmpint1
;---------------------------------
addd:
adddi,2
movbx,number3[di]
addax,bx;相加
adddi,2
jmpint3
subb:
adddi,2
movbx,number3[di]
subax,bx;相减
adddi,2
jmpint3
;---------------已处理完乘除运算---------------------
chubu:
movnumber3[di],bx;保存右括号或等号
subdi,2
movnumber3[di],ax;保存右括号或等号左边的数
movax,number3;ax被以NUMBER3中的初值
movdi,2
;----------处理加减运算----------------------------
int3:
movbx,number3[di]
cmpbx,2bh;加号
jeaddd
cmpbx,2dh;减号
jesubb
movresult,ax;将结果放在result缓冲区
RET
fraENDP
;----------------计算四则基本运算fra子程序在此结束-------------------
;----------------输出最终结果output子程序--------------------------
outputprocnear
leasi,Table;将上面定义的除数偏移地址放到SI中
movcx,5;定义下面循环次数为5次,因为有5个除数
movc2,0;若结果为负值,则它会被置1
movc3,0
movax,result;将运算结果放在AX
outgo:
xordx,dx;dx清零
cmpax,0;判断结果是否为负数
jlqb1
outgo1:
divwordptr[si];除bp值求万位,千位,百位,十位,个位;商存在了ax中,余数存在了dx中
oral,30h;转换成ascill码可用addal,30H
movbx,dx;将余数dx的值存入bx中,因为下面输出ax值时会改变dx值
cmpc3,0
jneoutgo2
pdjg:
cmpax,30h;商为零,除数比被除数大时,不把0商输出,直接进行下一次除法,比如计算结果是561,对于除数为10000和1000
jeoutgo4
jneoutgo2;商不为零是时,输出商
outgo2:
addc3,1
cmpc2,1
jefh
outgo3:
movdx,ax;输出商值,因为商放在AX中
movah,02;显示单个字符
int21h
outgo4:
movax,bx;将余数赋还给ax,准备下一次除法
addsi,2;SI加二,用以调用下一个被除数;
loopoutgo
callCRLF;回车换行
jmpstart1;跳回程序开始
ret
qb1:
NEGax;若结果为负数,则求补
movc2,1
jmpoutgo1
fh:
pushax;若之前进行过求补处理,则先输出一个负号,然后跳到outgo3输出商值
movdl,'-'
movah,2
int21h
popax
jmpoutgo3
outputendp
;-------------------------输出结果output子程序结束-------------------
;-------------------------回车换行crlf子程序-------------------------
CRLFPROCNEAR
MOVDL,0DH;回车
MOVAH,02H;
INT21H;
MOVDL,0AH;换行
MOVAH,02H;
INT21H;
RET
CRLFENDP
;-------------------回车换行crlf子程序在此结束----------------
codeends
endstart
;----------------------代码段定义完毕-------------------------
五、课程设计总结:
一周的课程设计结束了,我的收获很大。
通过课程设计的编程和对编程过程中遇到的问题的思考,有效的提高了我对汇编的认识和理解,切实的提高了我的编程能力,补全了我的不足。
通过这次课程设计,我巩固所了学过的知识,能用汇编语言熟练地运用顺序、选择、循环三大结构,进一步掌握了各个指令的功能,特别是转向指令,掌握了子程序的定义及调用。
在整个程序的编写中,调试占了很大部分的时间。
要想写好汇编语言的程序,必须认真对待代码的每一个细节,这对程序的调试是非常重要的。
通过这次实际动手能力的培养,我进一步熟悉了汇编语言的结构和使用方法,基本达到了能独立阅读、编制和调试一定规模的汇编语言程序的水平。
在这次课程设计的过程中使我意识到我们的工作是一个团队的工作,团队需要个人,个人也离不开团队,必须发扬团结协作的精神。
某个人的离群都可能导致导致整项工作的失败。
实习中只有一个人知道原理是远远不够的,必须让每个人都知道,否则一个人的错误,就有可能导致整个工作失败。
团结协作是我们实习成功的一项非常重要的保证。
而这次实习也正好锻炼我们这一点,这也是非常宝贵的。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 微机 设计 报告