首页 > 解决方案 > 8086 组件中的简单斐波那契打印机

问题描述

几天前我开始学习汇编,我正在尝试制作一个程序来打印最多 5 个字符的斐波那契数列,但是我的代码打印出奇怪的字符

我认为这是因为 ASCII 转换系统,但即使我将值 48 添加到数字中,它仍然不正确。

.model small 
.data
  lastFib DB 0
.code
  main PROC
    mov cx,5
    mov dl,48
  loopy: 
    add dl,lastFib 
    mov ah,2h          
    int 21h
    mov lastFib,dl   
    loop loopy 
  ENDP
end main

标签: assemblydosx86-16

解决方案


但我的代码打印出奇怪的字符

仅需要添加 48 才能将(小)数字输出为字符。你不能让这个加法 48 篡改你对斐波那契数的计算。在下面的代码中,我在调用 DOS 之前添加了 48,然后立即将添加返回。

目前,您的代码根本不计算任何斐波那契数。基本方案是:

xchg dl, lastFib   ; Exchange current with previous
add  dl, lastFib   ; Add previous to current

有 6 个单位的斐波那契数:1、1、2、3、5、8。
通过在计算下一个斐波那契数之前输出,下面的代码设法在一个循环中打印所有 6 个数字。第 7 个数字 (13) 已计算但从未显示。

.model small 
.data
  lastFib DB 0       ;previous
.code
  main PROC
    mov  cx, 6
    mov  dl, 1       ;current
  loopy:
    add  dl, 48      ;make character
    mov  ah, 02h
    int  21h
    sub  dl, 48      ;take back
    xchg dl, lastFib
    add  dl, lastFib
    loop loopy
  ENDP
end main

我们为什么不稍微优化一下代码呢?

  • 有大量可用的寄存器,没有理由将lastFib变量保存在内存中!
  • 我们可以避免缓慢的loop指令以及昂贵xchg的内存
  • 选择当前斐波那契数以外的寄存器DL将减少额外的“收回”指令。

由于涉及 DOS api 调用,这些更改都不会加速此代码。尽管如此,当没有这样的系统调用存在时,都有很好的优化。

.model small 
.code
  main PROC
    xor  cx, cx      ; Previous
    mov  bx, 1       ; Current
  loopy:
    lea  dx, [bx+48] ; Make character in DL
    mov  ah, 02h     ; DOS.PrintChar
    int  21h
    xchg bx, cx
    add  bx, cx
    cmp  bx, 10
    jb   loopy
  ENDP
end main

这一次,只要 in 中的数字BX保持一位数,循环就会继续。


推荐阅读