题目
从键盘输入n,计算其对应的斐波那契函数的fib(n),并输出结果。
流程图
思路
- 第二步定义的子程序的功能是这样子的。假如 a = 0,b = 1;此时定义c = b,b = b + c,a = c。这个功
能就意义递归推荐斐波那契数列,最后b值就是fib(n),这里递归的此时可能是输入的n值要减去1,因为
fib(1) = 1; - 在字符串转化为数的时候,可以采取str = ‘123’ 从字符串表头取值,清空S = 0, S = S * 10 + str[i] -
30H;然后i从0到2;字符串的输入不宜过长,不然寄存器无法保存fib(n)。 - 输入功能调用和输出功能调用
MOV DL,48 ; 十进制的48对应的ASCII值为0
MOV AH,0200H
int 21H ;会将字母0打印到屏幕上 MOV AH
0100H int 21H ;系统产生中断,直至从键盘录入一个字符至AL寄存器中
效果图
fib(2) = 1,fib(3) = 2,fib(123) = 41026
实现代码
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
; 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368
.model small
.data
str db 2 dup(10) ; 保存输入
fib dw 0,1,23 dup(-1) ; 保存斐波那契数
.stack
dw 128 dup(?)
.code
start:
mov ax, @data
mov ds, ax
mov si, 0 ; 下标
mov cx, 2
s1:
mov ah, 01h ; 输入
int 21h
cmp al, 13 ; 判断是否回车
je break1
sub al, 48 ; ASCII(0) = 48
mov str[si], al
inc si
loop s1
break1:
cmp cx, 0 ; 如果输入了 2 个数则换行
jne exit
mov dl, 10
mov ah, 02h
int 21h
exit:
cmp cx, 0
je next
; 1 位数
mov cl, str[0]
mov ch, 0
jmp short break2
next: ; 2 位数
mov al, str[0]
mov ah, 10
mul ah
mov bl, str[1]
mov bh, 0
add ax, bx
mov cx, ax
break2:
call function
mov ax, bx
mov bx, 0 ; 栈的高度
mov cx, 5 ; 0 - 65535 最大位数为 5
s2:
mov dl, 10
div dl
mov dh, 0
mov dl, ah
push dx
inc bx
mov ah, 0
cmp ax, 0
je break3
loop s2
break3:
mov cx, bx
s3:
pop dx
add dl, 48
mov ah, 02h
int 21h
loop s3
mov ax, 4c00h
int 21h
function:
push ax ; 保存 ax,因为乘法需要用到 ax
mov al, cl
mov ah, 0
mov dl, 2
mul dl
mov si, ax ; 2 * cx 对应斐波那契数组的坐标
cmp fib[si], -1 ; 检查是否已经计算过
je calculate
mov bx, fib[si] ; 直接使用计算好的值
jmp short return
calculate:
dec cx
call function
mov ax, bx
dec cx
call function
add ax, bx
mov bx, ax
add cx, 2 ; 恢复 cx
mov al, cl
mov ah, 0
mul dl
mov si, ax ; 将计算好的数值放入斐波那契数组中
mov fib[si], bx
return:
pop ax
ret
end start