X86汇编实现斐波那契数列

程序说明:

输入斐波那契数列的项数, 然后依次输出斐波那契数列, 输入的项数小于256且为数字, 计算的项数不能超过2^16次方, 输入失败是 不会回显数字

因为存结果是AX, 只有16位, 最大为2^16 = 65536,所以程序设置当输入过大时, 只会显示项数小于 65536前的项数

下面是程序的流程图

程序包括3个模块, 分别是主模块, INPUT模块(读取键盘中输入的合法数字), OUTPUT模块(输出数字)

主模块

INPUT模块

OUTPUT模块

代码及其详细注释


ASSUME CS:CODE,DS:DATA
DATA SEGMENT
MSG1 DB 13,10,'Please input the num of Fibonacci,no lager than 256 , N = $'
MSG2 DB 13,10,'Fibonacci Sequence is: $' ;提示信息 N DW 0
F1 DW 0
F2 DW 1 ;计算数列的两个加数
DATA ENDS
;
CODE SEGMENT
START:
MOV AX,DATA
MOV DS,AX ;导入数据
;
LEA DX,MSG1
MOV AH,9
INT 21H ;打印提示信息1 CALL INPUT ;调用INPUT模块, 得到项数 存到 CX中 CMP CX,1 ;如果CX < 1 输入不合法
JB EXIT ;直接退出 MOV N,CX ;令N = CX 即 N为数列项数 LEA DX,MSG2 ;打印输出信息 ‘Fibonacci Sequence is:’
MOV AH,9 ;调用的是9号方法 .09H号调用,字符串输出显示
INT 21H ;先处理第一个项
MOV DL,'1' ; 先把 1 放到输出区
MOV AH,2
INT 21H
MOV DL,' '
INT 21H ; 输出 1 和 空格
DEC N ; N --;
JZ EXIT ; 当 N = 0时,退出 LOOP:
MOV AX,F1 ; 把 AX = F1
ADD AX,F2 ; AX =+ F2
JC EXIT ; AX发生进位 即 AX不能表示数字
MOV BX,F2
MOV F1,BX ;不能 直接MOV F1,F2 不支持这样做
MOV F2,AX ; 把 F2 赋值给 F1 , AX (计算出来的一项) 赋值给 F2
CALL OUTPUT ; 调用输出模块 输出计算的项
MOV DL,' '
MOV AH,2
INT 21H ;输出空格
DEC N ; N--
JNZ LOOP ;跳转到循环LOOP JNZ是由标志位ZF 而ZF是算术运算可以改变的,
;这里可能使ZF发生改变的是上一个指令 DEC N , 当N != 0 条件成立
EXIT:
MOV AH,4CH
INT 21H ;退出程序
;
INPUT:
MOV BL,10 ; BL 为 10
MOV CX,0 ; CX 为 0 IN_X: ;输入数字 MOV AH,7
INT 21H ;读取数据 CMP AL,13 ; 读取的字符是 回车
JE IN_END ; 跳转到输入结束模块 CMP AL,'0' ; 输入不合法 就继续输入
JB IN_X
CMP AL,'9' ; 输入不合法 就继续输入
JA IN_X MOV DL,AL ;把合法数字 存入到DL MOV AH,2 ; 调用2号功能 输出刚才输入的字符
INT 21H
MOV AL,DL
SUB AL,30H ; 把assic码变成数字
MOV AH,0 ; AH 为 0
XCHG AX,CX ; 把cx变成刚输入的数字
MUL BL ; AX = AL * BL(10) 也就是乘以相应的权 百位数乘100 十位数乘10
ADD CX,AX ; CX += AX; cx表示的就是真正输入的斐波那契项数
;这里设置项数的最大值, 项数最大为256 如果输入大于256 就直接结束
CMP CH,0 ;判断CX的前8位是不是为0, 如果不为0, 说明大于256
JNZ IN_END ;大于256 直接结束输入
JMP IN_X ;否则继续输入 IN_END:
RET ;结束调用
;
OUTPUT:
MOV BX,10 ;BX 初始化为 10
MOV CX,0 ;CX 初始为 0
;会接着运行下面的代码
; 下面的代码用于把数字转换成字符串
;方法是每次把数除10 得到余数 压入栈中在,直到被除数为0, 然后依次输出栈顶字符 LOOP1:MOV DX,0 ; DX = 0
DIV BX ; AX为被除数 AX = AX / 10; 余数放在DX里 ,这就是最低位的数字
ADD DL,'0' ; 把DL 加上 '0' 此时 DL是能直接输出的字符数字
PUSH DX ; 把DX 压入栈
INC CX ; CX ++
CMP AX,0
JNZ LOOP1 ; 如果AX 不为 0, 就继续LOOP1
MOV AH,2
LOOP2:POP DX ;循环输出栈的字符
INT 21H
LOOP LOOP2
RET ;结束调用
;
CODE ENDS
END START

X86汇编——计算斐波那契数列程序(详细注释和流程图说明)的更多相关文章

  1. 使用并行的方法计算斐波那契数列 (Fibonacci)

    更新:我的同事Terry告诉我有一种矩阵运算的方式计算斐波那契数列,更适于并行.他还提供了利用TBB的parallel_reduce模板计算斐波那契数列的代码(在TBB示例代码的基础上修改得来,比原始 ...

  2. Android NDK入门实例 计算斐波那契数列一生成jni头文件

    最近要用到Android NDK,调用本地代码.就学了下Android NDK,顺便与大家分享.下面以一个具体的实例计算斐波那契数列,说明如何利用Android NDK,调用本地代码.以及比较本地代码 ...

  3. 以计算斐波那契数列为例说说动态规划算法(Dynamic Programming Algorithm Overlapping subproblems Optimal substructure Memoization Tabulation)

    动态规划(Dynamic Programming)是求解决策过程(decision process)最优化的数学方法.它的名字和动态没有关系,是Richard Bellman为了唬人而取的. 动态规划 ...

  4. 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)

    先科普一下什么叫斐波那契数列,以下内容摘自百度百科: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因意大利数学家列昂纳多·斐波那契(Leonardoda Fibonacci ...

  5. shell脚本计算斐波那契数列

    计算斐波那契数列 [1,1,2,3,5,8,,,,,] #!/bin/bash n=$ num=( ) i= while [[ $i -lt $n ]] do let num[$i]=num[$i-] ...

  6. java 递归及其经典应用--求阶乘、打印文件信息、计算斐波那契数列

    什么是递归 我先看下百度百科的解释: 一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的.用递归过程定义的函数,称为递归函数,例如连加.连乘及阶乘等.凡是递归的函数,都是可计算的,即 ...

  7. 关于Haskell计算斐波那契数列的思考

    背景 众所周知,Haskell语言是一门函数式编程语言.函数式编程语言的一大特点就是数值和对象都是不可变的,而这与经常需要对状态目前的值进行修改的动态规划算法似乎有些"格格不入", ...

  8. python计算斐波那契数列

    斐波那契数列就是黄金分割数列 第一项加第二项等于第三项,以此类推 第二项加第三项等于第四项 代码如下 这一段代码实现fib(n)函数返回第n项,PrintFN(m,n,i)函数实现输出第i项斐波那契数 ...

  9. Android NDK入门实例 计算斐波那契数列二生成.so库文件

    上一篇文章输生成了jni头文件,里面包含了本地C代码的信息,提供我们引用的C头文件.下面实现本地代码,再用ndk-build编译生成.so库文件.由于编译时要用到make和gcc,这里很多人是通过安装 ...

随机推荐

  1. GEDIT外部工具

    首先通过编辑-首选项-插件-外部命令来打开外部命令,然后在工具-Manage External Tools来添加新工具,工具代码使用bash语言. 代码使用方式:+添加新插件,在编辑框中粘贴代码,快捷 ...

  2. ant design pro : 依赖项 webpack-theme-color-replacer 最新版导致项目无法启动?

    重新装了一个项目的依赖,结果发现打不开了? 报错如下: This dependency was not found: * webpack-theme-color-replacer/client in ...

  3. echarts 实战 : 怎么处理特殊的图表数字 label ?

    所谓Label,就是在图表上面显示的那个数字. 但有的时候我们需要柱状图堆叠. 那如果我们需要所有数字都在外面,并且以 320/210/310/410/1320 这样的形式显示呢? 那么 echart ...

  4. javascript : 复杂数据结构拷贝实验

    数组深拷贝看起来很简单. array.concat()就行了. 但是,如果数组里有对象呢? 实际上,你以为你拷贝了对象,但实际上你只拷贝了对象的引用(指针)! 我们可以做个试验. // test le ...

  5. js的传递方式

    回头过来复习一下. 从一个变量向另一个变量复制的时候,复制过去以后,都是单独独立的变量,当你改变其中一个的时候,并不会影响另一个变量.他们只是value相同而已: var a = 1; var b= ...

  6. 完全卸载MySQL完整图文流程

    想把mlsql卸载了重装,看了许多文章试了很多方法都没办法完全卸载,直到看到了这篇文章, 可以完全卸载mysql,在这里谢谢博主,也拿出来分享给大家 原文链接:https://blog.csdn.ne ...

  7. 洛谷 P2403 [SDOI2010]所驼门王的宝藏 题解

    题目描述 分析 先放一张图便于理解 这一道题如果暴力建图会被卡成\(n^{2}\) 实际上,在我们暴力建图的时候,有很多边都是重复的 假如一行当中有许多横天门的话,我们就不必要把这一行当中的所有点和每 ...

  8. PHP rmdir() 函数

    定义和用法 rmdir() 函数删除空的目录. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE. 语法 rmdir(dir,context) 参数 描述 dir 必需.规定要删除的目录. ...

  9. 使用hibernate validate做参数校验

    1.为什么使用hibernate validate ​ 在开发http接口的时候,参数校验是必须有的一个环节,当参数校验较少的时候,一般是直接按照校验条件做校验,校验不通过,返回错误信息.比如以下校验 ...

  10. 强烈推荐的 IntelliJ IDEA 插件,别说我没告诉你

    为什么你的 Intellij IDEA 没别人的好用?还不是因为你缺少这几个插件啊! 善用 Intellij IDEA 插件可以提高我们的开发效率,今天和大家一起分享一下实际工作中常用的几款能提升幸福 ...