汇编语言解一元二次方程程序设计.docx
- 文档编号:24472258
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:27
- 大小:176.19KB
汇编语言解一元二次方程程序设计.docx
《汇编语言解一元二次方程程序设计.docx》由会员分享,可在线阅读,更多相关《汇编语言解一元二次方程程序设计.docx(27页珍藏版)》请在冰豆网上搜索。
汇编语言解一元二次方程程序设计
学号
课程设计
题目
求解一元二次方程程序设计
学院
专业
班级
姓名
指导教师
2013
年
1
月
11
日
课程设计任务书
学生姓名:
专业班级:
指导教师:
工作单位:
题目:
求解一元二次方程程序设计
初始条件:
带有编辑器、汇编程序、连接程序和调试程序的电脑一台。
要求完成的主要任务:
(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
采用汇编语言设计一个程序,求解一元二次方程
。
实现从键盘输入a,b,c的值,且-128≤a,b,c≤127;显示方程的解,-32768≤X1,X2≤32767;考虑所有的情况,包含共轭复根。
(1)设计任务及要求分析
(2)方案比较及认证说明
(3)系统原理阐述
(4)软件设计课题需要说明:
软件思想,流程图,源程序及程序注释
(5)调试记录及结果分析
(6)总结
(7)参考资料
(8)附录:
芯片资料或程序清单,软件演示屏幕拷贝图或硬件实物图
时间安排:
12月31日~1月2日:
收集资料,方案选择
1月3日~1月8日:
整体流程,程序细节
1月9日~1月10日:
调试程序,报告撰写
1月11日:
交设计报告,程序演示,答辩
指导教师签名:
年月日
系主任(或责任教师)签名:
年月日
目录
摘要1
1DOS功能调用2
1.1DOS功能简介2
1.2DOS输入/输出功能2
1.2.1单字符输入——0AH号2
1.2.2单字符输出——2号2
1.2.3过程终止——4CH号2
1.2.4子程序设计3
2解方程计算过程3
2.1一元二次方程
分析3
2.2求解一元二次方程的流程4
2.3各程序段分析编程4
2.3.1DATA数据段的定义4
2.3.2处理a、b、c的键盘输入6
2.3.3对a、b、c输入的数进行处理7
2.3.4对
进行的计算处理9
2.3.5对
的开方计算11
2.3.6计算处理及输出13
2.3.7结果显示操作18
3结果显示分析19
总结与体会22
参考文献23
附录24
摘要
解一元二次方程
。
实现从键盘输入a,b,c的值,且-128≤a,b,c≤127;显示方程的解,-32768≤X1,X2≤32767;考虑所有的情况,包含共轭复根。
这本来是一个很简单的数学问题,而要用汇编语言进行解决,就得有一套完整的方案。
编写汇编程序时,要有一个完整的流程图,这需要把自己的方案用流程图的方式简单的体现出来。
根据流程图编写所需要的程序,以完成解方程的目的。
将结果显示到桌面上,按“Q”或者“q”则退出程序。
之中有DOS功能的调用,也有一些新东西的学习。
解决这个编程问题,对微机原理的学习又加深啦!
汇编语言(AssemblyLanguage)是面向机器的程序设计语言。
汇编语言是一种功能很强的程序设计语言,也是利用计算机所有硬件特性并能直接控制硬件的语言。
汇编语言,作为一门语言,保持了机器语言的优点,具有直接和简捷的特点,可有效地访问、控制计算机的各种硬件设备,如磁盘、存储器、CPU、I/O端口等,且目标代码简短,占用内存少,执行速度快,是高效的程序设计语言。
虽然现在的高级语言很多,但汇编语言的作用并没有被取代,还在各个领域发挥重要的作用。
关键字:
汇编语言流程图DOS功能调用指令
解方程程序设计
1DOS功能调用
1.1DOS功能简介
DOS是美国Microsoft公司为IBMPC研制的磁盘操作系统(DiskOperatingSystem),也成为IBM-DOS或MS-DOS。
DOS不仅为用户提供了许多使用命令,而且还有用户可以直接调用上百个常用子程序。
对这些子程序的调用,成为系统调用功能。
这些子程序的功能主要是进行磁盘读/写、控制管理、内存管理、基本输入/输出管理等。
在使用时,用户不需要了解各种I/O端口硬件的详细情况就能直接完成对I/O接口的控制和管理。
为了使用方便,将所有子程序从1号开始编号,这些编号成为DOS功能调用号。
其调用过程为:
DOS功能调用号送AH寄存器;
如果需要,按要求给定输入参数;
写入中断指令“INT21H”。
调用结束,按功能使用其输出参数。
1.2DOS输入/输出功能
1.2.1单字符输入——0AH号
功能:
多个字符输入到缓冲区
输入参数:
DS:
DX=输入缓冲区首地址
输出参数:
DS:
DX=输入字符串所在缓冲区地址
1.2.2单字符输出——2号
功能:
从键盘输出个字符
输入参数:
DL=ASCII码
输出参数:
无
1.2.3过程终止——4CH号
该调用的功能是结束当前程序,并且返回调用它的程序。
如果在DEBUG状态下运行,则返回DEBUG;如果在DOS下运行。
则返回DOS;在汇编语言程序结束处加上“MOVAX,4C00H”和“INT21H”两条指令,以便于程序执行完毕,返回操作系统控制。
1.2.4子程序设计
子程序设计思想与主程序设计思想没什么区别。
若程序设计中采用调用子程序的方式,则使程序阅读起来清晰。
因为一个子程序完成一个功能,使得程序调试也方便。
子程序不能单独运行,可以提供给主程序调用、设计子程序要提供以下信息:
子程序的功能;调用时需要的参数;调用后提供的输出参数;子程序中所使用的寄存器。
2解方程计算过程
2.1一元二次方程
分析
一元二次方程
的求解,首先对其进行分析。
首先,a=0的情况不给于讨论,即在a=0是此一元二次方程不成立,需要重新给点a的值,同时,要对a、b、c进行输入,要保证他们都为数字。
再者要判断所得到的跟是不是重跟,即要判断
的大小,如果
=0,那么两个根重合,输出相同,如果
<0,那么次方程有两个共轭虚数跟,
>0,那么这个方程有两个实数根,不论其跟的情况如何,最后其求根公式求解,由此便可求得方程的跟。
2.2求解一元二次方程的流程
要用汇编语言对一元二次方程求解,首先编写流程图,根据思路,流程图如图1-1所示:
图1-1主程序流程图
2.3各程序段分析编程
2.3.1DATA数据段的定义
DATA数据段的定义,首先要定义的就是a、b、c的区间。
本次课设的定义区间将他们设为DB字节型变量,范围是(-128127),同时定义方程的两个解的以及他们的缓存区间,因为在做输入显示时,缓存区间的定义是很重要的,同时还要定义的就是Q/q返回程序和当a、b、c不在区间范围内的显示以及返回,代码指令如下所示:
datasegment
mes0db0dh,0ah,'inputcoefficientofequation:
-128<=a,b,c<=127:
','$'
mes1db0dh,0ah,'pleaseinputa=','$'
mes2db0dh,0ah,'pleaseinputb=','$'
mes3db0dh,0ah,'pleaseinputc=','$'
mes4db0dh,0ah,'inputdatanotintherange,pleaseinputagain','$'
mes5db0dh,0ah,'inputqorQtoexit,orinputotherkeytocontinue....','$'
mes6db0dh,0ah,'a=0leadstheequationisnotillegal!
','$'
mes7db0dh,0ah,'therootsoftheequation:
','$'
mes8db0dh,0ah,'pleaseinputdigital!
','$'
crlfdb0dh,0ah,'$'
同时定义a、b、c的输入最大值,用的是0AH指令,因为它定义三个BUFF,可以限制输入a、b、c的字符数,将字符数定义为最多输入四个,限制字符输入,并设置字符输入缓存,定义BUFF指令如下:
buff1db5;输入数据字符缓存
db?
db10dup(0)
设置字符缓存的用循环模式进行判断,储存。
0AH功能输入判断,设计了下面的程序:
process_indataproc
leadx,buff1
leasi,buff1
movah,0ah
int21h
movbx,dx;将0aH功能所得数据首地址备份
movcl,[bx+1];取输入数据串中字符个数
addsi,2
moval,[si]
cmpal,'-'
jzfirst_ok
mylab0:
cmpal,'0'
jlchar_not_ok
cmpal,'9'
jachar_not_ok
first_ok:
incsi
moval,[si]
loopmylab0
jmpdata_good
char_not_ok:
movchar_flag,1
jmpexit
2.3.2处理a、b、c的键盘输入
在键盘输入a、b、c时,会有不同的结果,首先,要输入a的值,有三种情况:
(1)a=0时,因为本题只是考虑二次方程,则a=0时不做定义,也就是在a=0时要重新输入a的值,输出定义为:
theequationisnotillegal!
(2)-128<=a<=127时,则为正确的a值输入,正常操作下面的程序。
(3)当a不是以上两种情况是,也就是a的输入不符合数据段定义的要求,比如带字母,特护符号等,则要重新输入a的值,并显示:
inputdigital!
下面讨论b、c的输入,b、c的输入是规则是相同的,也相同于a的输入,只是在0值时不做特殊讨论。
a、b、c的键盘输入定义在数据段已经定义,下面要做的就是判断a、b、c输入值的范围,判断范围的程序如下:
cmpax,-128
jldata_over
cmpax,127
jgdata_over
movover_flag,0
jmpfinish
data_over:
movover_flag,1
finish:
ret
2.3.3对a、b、c输入的数进行处理
对a、b、c输入的数进行处理,因为a、b、c的字符输入在缓存中,要一个一个的判断,输入的字符的ASCII码是不是在“1”与.“9”之间,如果在,则继续循环判断,如果不是,则重新输入,判断结果是在一个整的字符全部输入完成后来判断的,比如a的字符全部输入完全,如果输入的字符符合条件,但是为负数,在汇编语言中,负数要用它的补码来进行计算,如果为整数则直接储存,指令如下:
data_good:
leadx,buff1
leasi,buff1
movcl,[bx+1];取输入数据串中字符个数
addsi,2
moval,[si]
xorax,ax
xorbx,bx
xordx,dx
moval,[si];取键盘输入的第一个字符
deccl
cmpal,'-'
jzmylab2;输入为负数调入mylab2
subal,'0'
mylab1:
;正数转换
cmpcl,0
jzexit
movbl,10
mulbl
xorbx,bx
movbl,[si+1]
subbx,'0';将输入的字符转换为数值
addax,bx
incsi
deccl
jmpmylab1
mylab2:
;负数转换先处理符号位以后的数据,再用NEG指令变换
moval,[si+1]
subal,'0'
deccl
mylab4:
cmpcl,0
jzmylab3
movbl,10
mulbl
xorbx,bx
movbl,[si+2]
subbx,'0'
addax,bx
incsi
deccl
jmpmylab4
mylab3:
negax;将负数变为补码存储
exit:
ret,
下面进行对a、b、c输入符合上面条件的值进行判断是不是如何范围,a的处理比较复杂,因为a的考虑要多一些,所以,这里只对a进行讨论,其他同理可以得到,对a的处理程序如下:
showmes1
callprocess_indata;//处理输入的a值
cmpchar_flag,1
jnznot_char_a
showmes8
movchar_flag,0
jmpagain_a
not_char_a:
cmpal,0
jnzdata_ok
showmes6
jmpagain_a
data_ok:
callprocess_check;
movbl,over_flag
cmpbl,1
jnzdata_ok_a
showmes4
jmpagain_a
data_ok_a:
mova,al
2.3.4对
进行的计算处理
对
的计算,要考虑很多。
首先处理
,首先计算时要将其扩展为32位来储存,为了防止数据的溢出,并在扩展后将其高16位清零,指令如下:
moval,b
imulal;求b的平方,用带符号的乘法
movb2_L,ax;b的平方要用32位存储,防止数据溢出
movax,b2_H
xorb2_H,ax;b的平方高16位清零
下面对
计算处理,因为全为带符号数,那么要判断
的正负,判断的方式是使用指令testdx,8000h,判断正负之后,如果为负数,则取反加1,即利用补码来进行计算,正数直接参与下面的计算,并将结果存在DAT中。
计算指令如下:
moval,a
imulc;求a*c
movbx,4;4*a*c
imulbx;a,b,c为带符号的数,故所有乘法指令应该用带符号乘法
testdx,8000h;判断计算结果的正负;为保证b2-4*a*c运算
jzstep1
notax;如果为负数,则转换为正数,取反+1,因为为32位所以不好用NEG指令
notdx
addax,1
adcdx,0
movdat_H,dx;dat_Hdat_L存储4*a*c
movdat_L,ax
下面对
进行计算,要判断
的正负,如果为负数,取补吗,转换为正数计算,并且以sqrt_flag为标志位,负数为1,非负数为.0.。
并且减法运算为32为带符号减法,流程图如图2-1:
图2-1判断结果为正负流程图
根据流程图设计程序如下:
movdat_H,dx;dat_Hdat_L存储4*a*c
movdat_L,ax
movax,b2_L;32位减法b2-4ac
subax,dat_L
movdx,b2_H
sbbdx,dat_H
movsqrt_flag,1;b2-4ac正负标志:
1为正数,0为负数
jncnext;判断正负数
movsqrt_flag,0
subax,1;如果为负数,就转换为正数
sbbdx,0
notax
notdx
2.3.5对
的开方计算
对
的开方计算,因为汇编语言中没有关于开方计算的代码,所以用迭代法进行计算,迭代为从1开始,依次平方,知道大于
为止,再进行一下的循环判断,因为课设要求小数点后保留一位有效数字,那么计算之前将所以的数全部乘以10,那么
就是乘以100,32位数不能直接乘以100,采用的方法是循环叠加100次,因为要在正数部分循环迭代判断,得到的结果是原来计算结果的10倍。
指令如下:
next:
;由于32位乘法系统不支持故转换为100次循环加法
movsolve_H,dx;将结果保存
movsolve_L,ax
movcx,99;计算(b2-4ac)*100,将(b2-4ac)连续加100次
loop1:
addax,solve_L
adcdx,solve_H
looploop1
movtemp_H,dx
movtemp_L,ax
movsolve_H,dx;保存计算结果
movsolve_L,ax
xorcx,cx
step2:
;////////迭代运算从此开始
inccx;从1开始迭代,求开方
movax,cx
mulax
subax,solve_L;求x*x并和b2-4ac作差,并转换为正数
sbbdx,solve_H
jncstep3
subax,1
sbbdx,0
notax
notdx;将此次作差结果和上次比较,如果大于上次结果,则
step3:
cmpdx,temp_H;上次结果为开方的值,否则,继续迭代
jalast_step;dx>temp_H
jbstep4;dx cmpax,temp_L;dx=temp_H,ax>=temp_L jaelast_step step4: movtemp_H,dx;还没有找到开方的值,将此次结果保存,然后cx+1,继续迭代 movtemp_L,ax jmpstep2 last_step: deccx ret process_sqrtendp 2.3.6计算处理及输出 因为上面保存的结果为计算的10倍,在计算机显示的时候,字符是一位一位显示的,那么就要对得到的字符串进行处理,拆分,将各个字符拆分为单个的字符。 指令如下: get_num: cwd;除10取余,将各个数据拆分 divdivid adddx,'0' pushdx inccx cmpax,0 jnzget_num movax,cx to_buff: popbx;存储拆分结果 incsi addnum_1,1 movbyteptr[si],bl 为结果要求存储保留一位有效数字,分两种情况,一种是有小数部分,并且大于一位有效数字,那么结果取约分,如果结果为整数或者恰好为一位有效数字,那么直接参与下面的计算,指令如下: loop2: loopto_buff cmpax,1;小数点处理部分 jzone_bit movbl,byteptr[si];计算结果大于1位,处理小数点 incsi addnum_1,1 movbyteptr[si],bl movbyteptr[si-1],'.' jmpsolve_dis one_bit: ;计算结果为1位,处理小数点 movbl,[si] incsi incsi movbyteptr[si],bl movbyteptr[si-2],'0' movbyteptr[si-1],'.' addnum_1,2 solve_dis: ret 计算-b/2a的数值,依然要考虑保留小数点后一位有效数字,计算时计算的数为-10b/a,计算出结果要拆分,还原为原来的正确结果,并保存,计算时要却a的绝对值进行计算,计算程序与上面的相似。 计算 与上面相同。 计算 /2 的是两个值,首先判断的是开放结果的正负,开方结果为正数则为输出第一个解;为负数,则为第二个解,最后结果进行储存,结果中实数和虚数的输出,先计算输出实数部分,后计算输出虚数部分,指令如下: leasi,result_dis1 addsi,2 movnum_1,3 leadi,result_dis2 adddi,2 movnum_2,3 cmpsqrt_flag,1 jzpos_number;开方为正数,则跳转 ;方程的第一个解 showmes7 movbx,s1;-b/2a testbx,8000h;判断-b/2a的正负 jzdisp1 negbx incsi mov[si],'-' addnum_1,1 disp1: movax,bx callprocess_result1;-b/2a的值 incsi addnum_1,1 mov[si],'+' movax,s2 disp2: callprocess_result1;sqrt(b*b-4*a*c)/2a的值 incsi addnum_1,1 mov[si],'i' ;方程的第二个解 movbx,s1 testbx,8000h;判断-b/2a的正负 jzdisp3 negbx incdi addnum_2,1 mov[di],'-' disp3: movax,bx callprocess_result2 incdi addnum_2,1 mov[di],'-' movax,s2 disp4: callprocess_result2;存储显示计算结果的虚数部分 incdi addnum_2,1 mov[di],'i' jmpexit_p pos_number: ;计算结果为实数, ;方程的第一个实数解 showmes7 movax,s1_real pushax moval,a xorah,ah cbw movbx,ax popax cwd idivbx xordx,dx cwd idivtwo movbx,ax testbx,8000h;判断方程解的正负 jzdisp5 negbx incsi addnum_1,1 mov[si],'-' disp5: movax,bx callprocess_result1;计算方程的第二个解 movax,s2_real pushax moval,a xorah,ah cbw movbx,ax popax cwd idivbx xordx,dx cwd idivtwo movbx,ax testbx,8000h;判断方程解的正负 jzdisp6 negbx incdi addnum_2,1 mov[di],'-' disp6: movax,bx callprocess_result2;方程的第二个实数解 exit_p: ret 2.3
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 一元 二次方程 程序设计