奇偶阶乘求和汇编程序.docx

上传人:b****6 文档编号:7155298 上传时间:2023-01-21 格式:DOCX 页数:19 大小:69.06KB
下载 相关 举报
奇偶阶乘求和汇编程序.docx_第1页
第1页 / 共19页
奇偶阶乘求和汇编程序.docx_第2页
第2页 / 共19页
奇偶阶乘求和汇编程序.docx_第3页
第3页 / 共19页
奇偶阶乘求和汇编程序.docx_第4页
第4页 / 共19页
奇偶阶乘求和汇编程序.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

奇偶阶乘求和汇编程序.docx

《奇偶阶乘求和汇编程序.docx》由会员分享,可在线阅读,更多相关《奇偶阶乘求和汇编程序.docx(19页珍藏版)》请在冰豆网上搜索。

奇偶阶乘求和汇编程序.docx

奇偶阶乘求和汇编程序

摘要

近几十年,随着电子计算机的诞生和高速发展,社会和科技提到了前所未有的高度。

计算机技术的发展所带来的信息技术的飞速发展,给人类社会带来了进步,给人们的生活生产发生了巨大深刻的变化。

微机技术,在计算机发展过程中发挥了重要的作用。

微机技术使计算机在保持速度和性能的基础上,使得机器更加小巧。

典型代表是PC机普及到各行各业的各个领域。

不管是人们的生产或是生活,都离不开计算机,而且,计算机在以更快的速度在发展,其前途不可估量。

从我的的专业电气工程及其自动化来看,学好和灵活应用微机技术对我们来说有着十分重要的意义。

在大三上学期我们学习了微机原理和接口技术,对微机有了初步的了解。

学期结束后,为提高和巩固专业知识,我们进行了微机原理课程设计,主要是用汇编语言编程序代码使计算机完成相应的任务。

关键词:

微机汇编程序代码课程设计

目录

1总体方案分析1

1.1课程设计题目及要求1

1.2课程设计分析1

2方案流程图2

2.1方案分析2

2.2流程图3

3.关键程序设计及分析6

3.1求阶数程序6

3.2求阶数之和程序6

3.3变量输入及判断程序7

3.4数制转换程序8

4.运行结果及分析10

5心得体会11

6参考文献13

7程序清单14

1总体方案分析

1.1课程设计题目及要求

阶数求和汇编语言程序设计

初始条件:

Ø采用16位微处理器8086CPU以及86系列微型计算机的指令系统;

Ø软件设计平台可使用EMU8086软件,仿真设计平台可采用Proteus软件。

要求完成的主要任务:

Ø设计汇编语言程序,实现判断闰年的功能,具体功能要求如下:

(1)屏幕提示输入一个数字N(1位数);

(2)若N为奇数,则计算S=1!

+3!

+5!

+…+N!

的和;

若N为偶数,则计算S=2!

+4!

+6!

+…+N!

的和;

(3)可连续输入数字进行计算,直至单击“Q”或“q”键退出程序

1.2课程设计分析

本次课设是在键盘中输入一个1到9的数,然后求出其阶数之和,并显示出来。

但是,不同于直接的递增为1的阶乘求和,此次设计要求每次递增为2,即假如输入5,那么要求出1!

+3!

+5!

,如果为4,那么要求出2!

+4!

别看是小小的一点改动,程序设计难度上大有不同。

在设计汇编程序过程中,程序代码在求阶数、求阶数之和、将阶数之和输出三个部分的基础上,嵌套了双重循环。

考虑到我们用到的是16位汇编语言,而且寄存器有限,本题在编程序过程中会比较麻烦。

在进行课设之前,我有两种思路:

思路一:

首先计算n!

并把计算结果存放到相应存储区,然后然后判断n的奇偶来决定进行奇数求阶乘和还是偶数求阶乘和,然后把阶乘和结果转换成十进制,改成对应数字的ASSIC码值后,通过字符形式输出。

思路二:

首先计算n!

并把计算结果存放到相应存储区,形成列表。

这时不考虑奇偶的差异性,而是考虑递增2的共性,首先算出各个阶乘和并存放到另一存储区。

然后通过调用n对应的存储区间,进行十进制转换,ASSIC码转换,以字符的形式输出。

两种方案都是可行的,考虑我们需要重复进行输入输出操作,为了节省计算机的计算时间,提高计算机的工作效率,我们选择第二种方案。

2方案流程图

2.1方案分析

由于我们所选的方案是要将1到9的奇数或偶数阶乘之和给求出来,所以,我们需要先将1到9的阶乘分别求出来,并保存在指定的一段存储单元中,然后再从存储单元中调用1到9的阶乘,再把它们进行求和,这时需要注意的是奇数偶数调用的起始位置是不同的。

再分别将1到9的对应的阶乘和存储在另一个指定的存储单元中。

这两个存储单元都要事先定义好。

考虑到算出来的阶乘和比较大,所以要定义的是32位的字空间。

在汇编程序代码中,MUL指令的16位乘16位的结果是默认在DX:

AX当中,计算时需要多次用到,所以要注意使用;小于或等于8的阶乘小于65536,AX能保存,DX都为零,刚好在9的阶乘时的数才大于65536,需要AX,DX同时保存,这一点给程序的设计和调试过程中需要加以留心。

在求阶数之和过程中,只需保存了阶数的存储单元的数调出,再进行计算即可,在本次设计程序中,还是保持将高16为放在DX,低16位放在AX中。

值得注意的是,在进行低16位的求和计算中,会出现溢出的可能,所以需要考虑CF的值。

当在指定的存储空间段中保存了1到9的阶数之和,要用到的时候只需调用即可。

单字符输入指令1号中断中,得到的字符以ASCII码的形式存在AL中,所以还需程序将其ASCII码转换成其所表示的值。

然后在用到其值进行偏移地址的计算,取出其阶数之和那个值。

在程序结尾十进制的转换需要考虑各个寄存器间的关系。

最后进行字符输出的时候特别需要注意判断是否完全输出的方法。

 

2.2流程图

根据所设计好的方案和计划,设计出流程图。

开始

 

定义各个存储空间

 

si←buf的首地址

ax,bx←1

 

ax←ax×bx

[si]←ax

[si+2]←dx

bx>9?

si←si+4

bx←bx+1

N

Y

si←buff的首地址

di←result的首地址

bp←1

dx←[si]

dx←[si+2]

 

cf←0

ax←ax+cx

dx←dx+bx+cf

[di]←ax

[di+2]←dx

di←di+8

si←si+8

cx←[si]

bx←[si+2]

①②

bp←bp+2

bp>9?

N

 

Y

si←buff的首地址

di←result的首地址

bp←1

ax←[si]

dx←[si+2]

cf←0

ax←ax+cx

dx←dx+bx+cf

[di+4]←ax

[di+6]←dx

di←di+8

si←si+8

cx←[di+4]

bx←[di+6]

bp←bp+2

bp>8?

N

Y

dx←buff2的首地址

调用2号中断,在屏幕上显示提示输入字符串

在屏幕上输出错误信息

调用1号中断,在键盘上输入一个数字

判断输入的数是否是0到9

判断输入的数是否等于Q或q

N

N

YY

将输入的字符转化成其所代表的值,并形成偏移地址

结束

把result中算好的阶数之和转换成ASCII值,逐个字符输出

图1程序流程图

设计好流程图后,成功将程序的过程理清楚,给程序设计和调试带来了方便。

3.关键程序设计及分析

3.1求阶数程序

根据报告要求和设计的方案需要,设计了求1到9的阶数,并分别将它们的阶乘放在以buff为首地址的存储空间中,程序段,如下

movax,data

movds,ax

movsi,offsetbuff;把buff的偏移首地址给si,buff:

n!

存储区

movax,01h

movbx,01h

loop:

mulbx;计算1到9的阶乘,并保存到buff

mov[si],ax;n!

低4位给ax

mov[si+2],dx;n!

高4位给dx

addsi,04h;每次指针加4

incbx

cmpbx,09h;循环9次

jnaloop

此段程序主要是将1到bx的数相乘,得到bx的阶乘,分别存在以偏移地址为si和si+2的存储单元中,si也随着bx从1到9的每次变化加4。

此循环的计数次数由bx与9比较得出。

3.2求阶数之和程序

为求奇数或偶数的阶数和,我设计了下面的汇编程序段:

1、奇数的阶乘和求法:

movsi,offsetbuff;阶数存储单元

movdi,offsetresult;result:

阶数之和存储单元,di为偏移首地址

movax,[si];调用1!

数据到dx:

ax

movdx,[si+2]

movbx,00h

movbp,01h

movcx,00h

loop0:

clc;计算奇数阶乘之和,并保存到result的对应奇数位

addax,cx

adcdx,bx;加法进位

mov[di],ax

mov[di+2],dx

adddi,08h;disi分别加8

addsi,08h

movcx,[si]

movbx,[si+2]

addbp,2

cmpbp,09h;bp递增2控制循环次数

jnaloop0;bp不高于9则循环loop0

2、偶数的阶乘和求法:

movsi,offsetbuff;阶数存储单元

movdi,offsetresult;阶数之和存储单元

movax,[si]

movdx,[si+2]

movbx,00h

movbp,01h

movcx,01h

loop1:

clc;计算偶数阶乘之和,并保存到result的对应偶数位

addax,cx

adcdx,bx

mov[di+4],ax

mov[di+6],dx

adddi,08h;disi分别加8

addsi,08h

movcx,[si+4]

movbx,[si+6]

addbp,2

cmpbp,08h

jnaloop1

前面已经将1到9的阶乘算出,并存在以buff为首地址的存储空间中,此程序段主要是将奇数(或偶数)的阶乘从存储单元中调出,并进行相加,然后将所加的值分别存在以[di]和[di+2](或[di+4]和[di+6])为偏移地址的存储空间中,di随着循环加8,si也加8,bp也从1(或2)每次递增2变化到9(或8)。

此段程序的关键是对循环次数的控制。

3.3变量输入及判断程序

根据题目的要求,设计以下输入程序,并完成判断,程序段如下:

loop2:

leadx,buff2;输出提示符,buff2:

请输入一位数1到9

movah,9;多字符输出

int21h

movah,1;取一个数

int21h

cmpal,'q';判断是不是Q或q

jzloop3;是则转移到结束程序loop3

cmpal,'Q'

jzloop3

cmpal,'1';与1比较

jbloop4;低于1转移到loop4:

请输入1-9!

cmpal,'9'

jaloop4;高于9转移

此段程序中使用到的知识点主要有中断的调用和利用ASSIC码进行比较两点。

相对来说是本次程序设计中比较容易理解和掌握的方面。

根据设计要求需要在屏幕上显示提示文字,所以本段开头就使用了9号中断,多字符的输出。

3.4数制转换程序

得到输入的字符后,需要将其转换成对应数值,程序中存储的值是16进制数,要将数以10进制的字符输出,需要进行数制变换,为此设计了以下程序:

subal,30h;得出n

subal,01h

movbl,04h;每次偏移4×(n-1)字节

mulbl

movdi,offsetresult

movbp,offsety

adddi,ax

movax,[di];取对应阶乘和给dx,ax

movdx,[di+2]

s:

movcx,10

calldivdw;调用divdw程序

pushdx

addcl,30h;把数字转换为ASCII码

movds:

[bp],cl;把ASCII码放到内存中

popdx

pushax

pushdx

addax,dx;每位的数字是否完全输出

jzgout

popdx

popax

incbp

jmps

gout:

movdl,ds:

[bp]

movah,2

int21h

cmpbp,offsety;是否全部输出

jzok

decbp

jmpgout

ok:

leadx,next

movah,9

int21h

jmploop5

loop4:

leadx,buff1

movah,9

int21h

loop5:

jmploop2

loop3:

movax,4c00h

int21h

;参数:

(ax)=dw型低16位数据

;(dx)=dw型高16位数据

;(cx)=除数

;返回:

(dx)=结果的高16位,(ax)=结果的低16位

;(cx)=余数

;32位除16位,可以防止溢出!

divdwproc;子程序定义开始,功能是分离各位数字出来

pushax

movax,dx

movdx,0

divcx

movbx,ax;原dx值除以10的商通过ax暂存bx中

popax

divcx;除以10,商在ax,余数在dx

movcx,dx

movdx,bx

ret;子程序定义结束

divdwendp

当输入1到9的数N后,其实计算机内部存储的是该数的ASCII码,将其减30H得到其十进制数值。

然后用result的偏移地址加上4×(n-1)得到存储n的阶乘之和的存储空间的地址,然后进行寻址。

根据偏移地址调出来的N的阶数之和是16进制的,所以将其逐步除以10得到其各个10进制数值,然后再转换成ASCII码的值存储到y,这时bp递增,然后递减bp使字符输出。

此处循环次数的判定由dx:

ax即除以10后的商与余数是否为零决定。

在程序相应的地方加入了回车换行,使显示更清晰。

4.运行结果及分析

将设计好的程序放在EMU8086中运行,得到的结果,满足任务书上的要求。

下图是汇编程序运行后输入不同的符号产生的结果:

图2汇编程序运行结果图

图3按下Q键程序退出提示框

当运行程序后,屏幕上显示:

PLEASEPRESSANUMBER

IFYOUWANTTOIFYOUWANTTOQUIT,PRESSQorq

输入的数属于1到9时,屏幕上显示正确的结果,而且可以循环输入输出;当输入的符号位Q或q时,程序停止运行,弹出如图2所示的信息提示框,表明程序停止;当输入其他符号时,屏幕上显示:

Pleasepress1to9!

!

的警示符号。

 

5心得体会

不知要怎样开头写自己的心得体会,不只是连续三天疯狂的设计与调试搅的我头昏脑胀,还有那说不清道不明的五味杂陈。

在紧张的考试周过去后,我满以为可以痛痛快快的玩几天,因为我抽到的课程设计题目难度分是最低的阶乘求和问题。

可是当我在上网搜索尽可能详尽的资料之后,还是无法编出能够运行出结果的程序时,我才明白接近机器语言的汇编程序没有我想象的那么简单。

虽然以前学过C语言,对于阶乘求和这个问题也不陌生,对于阶乘求和的原理步骤更是一清二楚,但是当面对那稀缺而又淘气的寄存器时,不得不唉声叹气。

汇编语言和高级语言的差异一下子就体现出来。

汇编语言更接近机器码,所以指令都比较原始,不想高级语言那样可以比较容易地和具体的物理意义联系起来。

虽然清楚主要的步骤,却又无从下手,通过一步一步的运行于分析才能慢慢的理解书上一些程序的意思。

在此次的编程中,我感觉最不容易的就是阶乘和的求法和进制之间的转换,比如要输出一个数据,必须先转换成字符或字符串才能进行输出。

没有高级语言丰富的指令,汇编语言的编写简直是一种数学与逻辑,虚拟与现实的完美结合。

当我在经历近百次的设计修改调试运行终于得到想要的结果时,那一种成功的喜悦与激动冲扫了我多日的疲倦。

有了这一次的经历,我才真正认识到熟能生巧的重要性。

因为汇编程序比较麻烦,经常用到地址和跳转等程序,如果平时不仔细听老师讲课,就很难判断该用哪个指令,这样就会事倍功半,弄不好就会做不出来。

虽然在这次课程设计中遇到了很多困难与问题,但是在自己的努力和老师的指导下,我最终达到了设计的要求,完成了本次课程设计。

相比以前的课程设计,这次的课设花费了我大量的时间与精力,但是,一分耕耘,一分收获。

从刚开始的毫无头绪,慢慢的一步步的对照调试修改,到后来成功运行出结果。

这个过程无疑是痛并快乐的!

本次课设结束后,我知道自己的能力还需要进一步的提高。

更重要的是,我对于这仅有0与1的简单却又最复杂的语言充满了好奇。

以后我将会经常试着编写一些小程序来提高自己的水平

从昨天晚上6点到今天早上6点,饱含我的努力的微机原理课程设计终于完成了。

6参考文献

[1]彭虎等编著.微机原理与接口技术(第二版).北京:

电子工业出版社,2008

[2]沈美明,温东禅.IBM-PC汇编语句程序设计(第2版).北京:

清华大学出版社,2001

[3]任向明,卢惠林.汇编语言程序设计实用教程.北京:

清华大学出版社,2009

[4]马力妮.80x86汇编语言程序设计.北京:

机械工业出版社,2004

 

7程序清单

datasegment

buff2DB'PLEASEPRESSANUMBER',0DH,0AH

DB'IFYOUWANTTOQUIT,PRESSQorq',0DH,0AH,'$'

buffdw18dup(?

resultdw18dup(?

ydw100dup(?

nextdb0dh,0ah,0dh,0ah,'$'

next2db0dh,0ah,'Theresultis','$'

buff1db0dh,0ah,'Pleasepress1to9!

!

',0dh,0ah,0dh,0ah,'$'

dataends

codesegment

assumecs:

code,ds:

data

start:

movax,data

movds,ax

movsi,offsetbuff;把buff的偏移首地址给si,buff:

n!

存储区

movax,01h

movbx,01h

loop:

mulbx;计算1到9的阶乘,并保存到buff

mov[si],ax;n!

低4位给ax

mov[si+2],dx;n!

高4位给dx

addsi,04h;每次指针加4

incbx

cmpbx,09h;循环9次

jnaloop;bx不高于9则转移到loop

movsi,offsetbuff;阶数存储单元

movdi,offsetresult;result:

阶数之和存储单元,di为偏移首地址

movax,[si];调用1!

数据到dx:

ax

movdx,[si+2]

movbx,00h

movbp,01h

movcx,00h

loop0:

clc;计算奇数阶乘之和,并保存到result的对应奇数位

addax,cx

adcdx,bx;加法进位

mov[di],ax

mov[di+2],dx

adddi,08h;disi分别加8

addsi,08h

movcx,[si]

movbx,[si+2]

addbp,2

cmpbp,09h;bp递增2控制循环次数

jnaloop0;bp不高于9则循环loop0

movsi,offsetbuff;阶数存储单元

movdi,offsetresult;阶数之和存储单元

movax,[si]

movdx,[si+2]

movbx,00h

movbp,01h

movcx,01h

loop1:

clc;计算偶数阶乘之和,并保存到result的对应偶数位

addax,cx

adcdx,bx

mov[di+4],ax

mov[di+6],dx

adddi,08h;disi分别加8

addsi,08h

movcx,[si+4]

movbx,[si+6]

addbp,2

cmpbp,08h

jnaloop1

 

;---------------------------------------------------

loop2:

leadx,buff2;输出提示符,buff2:

请输入一位数1到9

movah,9;多字符输出

int21h

movah,1;取一个数

int21h

cmpal,'q';判断是不是Q或q

jzloop3;是则转移到结束程序loop3

cmpal,'Q'

jzloop3

cmpal,'1';与1比较

jbloop4;低于1转移到loop4:

请输入1-9!

cmpal,'9'

jaloop4;高于9转移

xorah,ah

pushax;保护ax

leadx,next2;输出;字符“结果是:

movah,9

int21h

xorah,ah

xordx,dx

popax

subal,30h;得出n

subal,01h

movbl,04h;每次偏移4×(n-1)字节

mulbl

movdi,offsetresult

movbp,offsety

adddi,ax

movax,[di];取对应阶乘和给dx,ax

movdx,[di+2]

s:

movcx,10

calldivdw;调用divdw程序

pushdx

addcl,30h;把数字转换为ASCII码

movds:

[bp],cl;把ASCII码放到内存中

popdx

pushax

pushdx

addax,dx;每个位的数字输出完没

jzgout

popdx

popax

incbp

jmps

gout:

movdl,ds:

[bp]

movah,2

int21h

cmpbp,offsety;输出完了没

jzok

decbp

jmpgout

ok:

leadx,next

movah,9

int21h

jmploop5

loop4:

leadx,buff1

movah,9

int21h

loop5:

jmploop2

loop3:

movax,4c00h

int21h

;参数:

(ax)=dword型低16位数据

;(dx)=dword型高16位数据

;(cx)=除数

;返回:

(dx)=结果的高16位,(ax)=结果的低16位

;(cx)=余数

;32位除16位,可以防止溢出!

divdwproc;子程序定义开始,功能是分离各个数字出来

pushax

movax,dx

movdx,0

divcx

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1