汇编语言斐波那锲数列.docx

上传人:b****8 文档编号:29549196 上传时间:2023-07-24 格式:DOCX 页数:14 大小:57.53KB
下载 相关 举报
汇编语言斐波那锲数列.docx_第1页
第1页 / 共14页
汇编语言斐波那锲数列.docx_第2页
第2页 / 共14页
汇编语言斐波那锲数列.docx_第3页
第3页 / 共14页
汇编语言斐波那锲数列.docx_第4页
第4页 / 共14页
汇编语言斐波那锲数列.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

汇编语言斐波那锲数列.docx

《汇编语言斐波那锲数列.docx》由会员分享,可在线阅读,更多相关《汇编语言斐波那锲数列.docx(14页珍藏版)》请在冰豆网上搜索。

汇编语言斐波那锲数列.docx

汇编语言斐波那锲数列

 

汇编语言实验报告

 

学院:

***

班级:

***

***

学号:

***

指导老师:

**

 

 

实验一斐波那契数列

1.设计要求

用递归的方法求斐波那契的第24项(N=24),并将结果用十进制显示出来

输出FIB(24)的值

2.设计思想和实施方案论述

FIB函数采用子程序递归调用方法,实现求斐波那契数列

先写出高级语言中的斐波那契递归函数:

Intfib(intN)

{

If(N==1||N==0)result=1;

Elseresult=fib(n-1)+fib(n-2);

Returnresult;

}

其函数为高级语言的形式,其中result=fib(n-1)+fib(n-2)隐含了几个操作可把它展开为:

N=N-1;注意到这里的N是形参(局部变量)与调用程序的实参不是同一个变量

Inta=fib(N)

N=N-1

Intb=fib(N)

Result=a+b;

由此可知几个重要实现地方:

a)保存现场:

N在一个fib函数里面是局部变量,当系统调用子程序时需要保存这个局部变量,在返回时需要恢复:

SUBTPROCNEAR

PUSHAX

PUSHBX

…….

…….

POPBX

POPAX

SUBTENDP;采用保存恢复寄存器的形式

b)参数传递:

其中的N在调用fib传参时是作为实参,在被调用函数中还需要被使用,这是参数的传递,这里采用通过数据区传递参数(同全局变量)

c)返回值:

最后的result在高级语言中是通过将result赋给一个临时变量(调用该函数的程序)然后释放result这个局部变量,在本程序中采用寄存器直接传递的方法,所以在Fib函数中将result赋给一个寄存器,然后不保存它,让其传递到上层调用函数中去。

3.课程设计中遇到的问题及解决方案

●遇到的问题

在编写斐波那契函数的过程中主要遇到了问题是保存现场的问题,在高级语言中,对子程序调用时,系统会自动为我们保存当前程序的现场指令地址,局部变量。

而在汇编中除了现场指令地址保存外,其他的工作都必须我们自己完成,所以在对子程序调用时,怎么保存当前的局部变量,怎么传递参数到将要调用的函数中去使用,都是很难理顺思路的地方。

●解决方案

第一:

明确哪些是局部变量,在调用完子程序返回时要恢复的。

第二:

局部变量作为实参,与被调用的子程序中的形参的区别。

第三:

确保有压栈就必须对应出栈,且系统的中断指令地址的保存与我们使用的栈是同一个栈

解决方案在上面已经写过,就没有在复述了

4.程序流程图

5.源程序及注释

DATASSEGMENT

message1db"inputthenumber","$"

NUM=18h;修改此处获得第N项斐波那契数列值

Ndw0;用于传参的N

DATASENDS

CODESSEGMENT

ASSUMECS:

CODES,DS:

DATAS

Mainprocfar

START:

pushds

subax,ax

pushax

movax,DATAS

movds,ax

movbyteptrN,NUM

callFIB;调用Fib子程序

movdx,ax

;callOutput_CTLF

callPrintOX;将十进制转换为十六进制输出

movah,1

int21h;等待退出屏幕

ret

Mainendp

;outputCTLF

Output_CTLFprocNear

pushax

pushdx

movah,02h

movdl,0dh

int21h

movdl,0ah

int21h

popdx

popax

ret

Output_CTLFendp

 

;inputvalueindx

PrintOXprocnear

movcl,4

loop1:

pushcx

movcl,4

roldx,cl

movax,dx

popcx

andax,000fh

cmpax,000ah

jlLessThanA

addax,07h

LessThanA:

addax,30h

pushdx

movdl,al

movah,2

int21h

popdx

looploop1

ret

PrintOXendp

FIBprocnear;FIB子函数

pushcx;cx与bx为局部变量

pushbx

movcx,N;使用N作为实参传参,cx为形参

cmpcx,1;相当于if(N=<1)

jleless_equal_1

deccx;相当于N-1

movN,cx;使用N作为实参传参

callFIB;FIB(N-1)

movbx,ax

deccx;相当于N-1

movN,cx;使用N作为实参传参

callFIB;FIB(N-1)

addax,bx;ax中保存FIB(N-1)+FIB(N-2),并且作为返回值

jmpender

less_equal_1:

movax,1;如果N<=1result=1

ender:

popbx

popcx

ret

FIBendp

CODESENDS

endstart

实验二统计学生成绩

1.设计要求

设计10个学生的成绩分别为56、69、84、82、73、88、99、63、100和80分。

试编制程序分别统计低于60分、60-69分、70-79分、80-89分、90-99分及100分的人数,并存放到S5、S6、S7、S8、S9及S10单元中。

2.设计思想和实施方案论述

定义以x为数组名的含10个单元的一维数组,分别存放10个学生的成绩;定义变量S5、S6、S7、S8、S9及S10,初始化为0,以存放各成绩阶段的人数,以上均以字为存储单元长度。

建立子程序SEARCH,用以查找学生成绩并进行各成绩阶段的人数统计,并在主程序中调用。

其中,统计应用公式——(成绩)/10-5)*2——根据成绩相s5的相对地址变化量来进行存储。

3.典型程序模块及典型编程技巧分析

子程序SEARCH(统计人数)

SEARCH:

MOVSI,0

NEXT:

MOVAX,x[SI]

MOVBX,10

DIVBL

MOVBL,AL

SUBBX,5

SALBX,1

INCS5[BX]

ADDSI,2

LOOPNEXT

RET

子程序PRINTMen人数

PRINTMen:

MOVAH,02H

INT21H

MOVDL,''

MOVAH,02H

INT21H

RET

编程技巧:

采用子程序方法,使程序更易分析,模块更清晰,利用循环和相对地址变化量来减少程序的冗余度,是其看起来精简和更易分析。

4.课程设计中遇到的问题及解决方法

1、对汇编语言编程的基本结构都不会

解决方法:

看书,多看几个程序,便熟悉了基本结构datasegment,codesegment等。

2、数组的地址分配方式很糊涂,其存储单元的长度与首地址的关系

解决方法:

请教老师同学,在多次练习小习题后,进行画图分析

3、子程序的使用方法

解决方法:

多看程序

4、公式的汇编语言转换

解决方法:

“心急吃不了”热豆腐,将大化小,化繁为易,一步步计算

5.程序流程图,程序清单和程序注释

 

子程序SEARCH

 

 

6.程序清单和注释

DATASEGMENT;数据段开始

xDW56,69,84,82,73,88,99,63,100,80;定义数组,以存放学生成绩

S5sDW0;定义变量s5,表示分数50-59分统计结果

S6DW0;定义变量s6,表示分数60-69分统计结果

S7DW0;定义变量s7,表示分数70-79分统计结果

S8DW0;定义变量s8,表示分数80-89分统计结果

S9DW0;定义变量s9,表示分数90-99分统计结果

S10DW0;定义变量s10,表示100分统计结果

DATAENDS;数据段结束

CODESEGMENT;代码段开始

MAINPROCFAR;MAIN函数声明

ASSUMECS:

CODE,DS:

DATA

START:

PUSHDS;过程开始

SUBAX,AX

PUSHAX

MOVAX,DATA

MOVDS,AX;初始化

BEGIN:

MOVCX,10;BEGIN函数开始

CALLSEARCH;调用统计人数子程序

MOVDL,BYTEPTRS5

ADDDL,30H

CALLPRINT;将分数50-59分统计结果赋值s5并输出

MOVDL,BYTEPTRS6

ADDDL,30H

CALLPRINT;将分数60-69分统计结果赋值s6并输出

MOVDL,BYTEPTRS7

ADDDL,30H

CALLPRINT;将分数70-79分统计结果赋值s7并输出

MOVDL,BYTEPTRS8

ADDDL,30H

CALLPRINT;将分数80-89分统计结果赋值s8并输出

MOVDL,BYTEPTRS9

ADDDL,30H

CALLPRINT;将分数90-99分统计结果赋值s9并输出

MOVDL,BYTEPTRS10

ADDDL,30H

CALLPRINT;将分数100分统计结果赋值s10并输出

RET

MAINENDP;MAIN主程序结束

SEARCHPROCNEAR;SEARCH子程序开始

MOVSI,0;初始化地址变化量为0

NEXT:

MOVAX,x[SI]

MOVBX,10;根据成绩计算相对S5的地址变化量

DIVBL;计算公式((成绩)/10-5)*2送(BX)

MOVBL,AL;(BH)保持为0不变

SUBBX,5;只统计50分以上成绩

SALBX,1;(BX)*2

INCS5[BX];S5是S5,S6,S7,S8,S9和S10单元的首地址

ADDSI,2

LOOPNEXT

RET

SEARCHENDP;SEARCH子程序结束

PRINTPROCNEAR;输出统计结果子程序

MOVAH,02H

INT21H

MOVDL,''

MOVAH,02H

INT21H

RET

PRINTENDP;PRINT子程序结束

CODEENDS;代码段结束

ENDSTART

 

收获与体会

汇编语言是一门低级语言,所以在程序设计的过程中我明显的感觉到一个词:

底层!

如,输入输出时要对每一位数值位进行处理,加深了对高级语言中输入输出格式的理解;子程序调用时需要自己设计分析堆栈的空间的分配情况,让我明白保存现场的意义及实现方式;使用变量时要仔细分配急度缺乏的寄存器资源,这也是程序优化的核心思想;甚至是要考虑到变量因为类型的不同储存的方式也不同,以及使用很少的指令集,自己编写出一些实用功能的函数,因为底层,指令不便于阅读所以模块化,规化在这里体现的尤为的重要,注释及程序文档则是比不可少的,不然由几条指令变化出来的这么多功能很难再短时间读懂。

此外,对汇编程序的调试也是一大难点,由于其完全是DOS下的编译环境,而且出错时给出的提示信息也很单一,所以更加需要以一种“单模块调试驱动编程”的方式编写,一次性编再编译会给后续的调试修改带来很大的困难,而先逐个编写出单个模块,然后调试通过后再编写下一个模块,如此每一次的调试时的错误会大大减少(因为面对的不确定代码少了),调试的时间自然就缩短了,这还是其次,“单模块调试驱动编程”如果想修改一些功能,目标代码也大大的减少,益处颇多啊~~

高级语言与汇编的区别就像,泡茶时,高级语言注意的是泡茶的流程,而汇编注意的还有是用左手还是用右手拿茶壶?

参考书籍:

《IBM-PC汇编语言程序设计》美明温冬婵

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

当前位置:首页 > 初中教育 > 政史地

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

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