秋月琥珀

ASM-递归计算前50个斐波那契数列

这回是递归算法,摸了好久鱼才动手写了一下
没做记忆化,后面几个算起来究极慢,可以算到明年
迫真 f(n)没dp,你慢死了


输出还是以前的方法
依旧是没有代码高亮
ps:试了一下,在10,000,000周期每秒的速度下,算到第49项花了4个小时。。。
.MODEL SMALL
.DATA
    VAR1L    DD 1
    VAR1H    DD 0
    VAR2L    DD 1
    VAR2H    DD 0
    VAR3L    DD 0
    VAR3H    DD 0
    TIMES    DD 1
    TEMPL    DD 0
    TEMPH    DD 0
    TEMPOUTL DD 0
    TEMPOUTH DD 0
.STACK 4096

.CODE
MAIN PROC FAR
.386

    START: 
           MOV  ECX,1
           MOV  VAR1L,ECX
           MOV  ECX,1
           MOV  VAR2L,ECX
           MOV  ECX,1
           MOV  TIMES,ECX
           MOV  ECX,0
           MOV  VAR1H,ECX
           MOV  VAR2H,ECX
           MOV  VAR3L,ECX
           MOV  VAR3H,ECX
            MOV ECX,1
    COUNT:
        PUSHAD
        CALL FIB
        PUSHAD
        CALL    OUTPUT
        POPAD
        POPAD
        INC ECX
        CMP ECX,50
        JE EXIT
        JMP COUNT


    EXIT:  
           MOV  AH,4CH
           INT  21H
MAIN ENDP
;递归计算代码块
FIB PROC NEAR
        CMP ECX,1
        JE  RETURN1
        CMP ECX,2
        JE  RETURN1 
        PUSH ECX
        DEC ECX
        CALL FIB
        POP ECX
        PUSH ECX
        PUSH EAX
        PUSH EDX
        DEC ECX
        DEC ECX
        CALL FIB
        MOV VAR3H,EDX
        MOV VAR3L,EAX
        POP EDX
        POP EAX
        POP ECX
        MOV VAR2H,EDX
        MOV VAR2L,EAX
        CLC
        MOV EAX,VAR3L
        ADC EAX,VAR2L
        MOV VAR1L,EAX
        MOV EDX,VAR3H
        ADC EDX,VAR2H
        MOV VAR1H,EDX

        RET


    RETURN1:
        MOV EDX,0
        MOV EAX,1
        RET
    FIB ENDP

    OUTPUT PROC NEAR
           MOV  EDX,VAR1H
           MOV  EcX,VAR1L
           push ecx
           mov  eax,ecx
           mov  di,0        ;di记录数字有几位
           mov  ebx,10      ;除数10
           div  ebx
           add  edx,30h     ;余数+30h变为对应的十进制ascll码
           push edx         ;低位入栈
           inc  di          ;位数+1
    s:     
           mov  edx,0
           mov  ebx,10      ;除数10
           div  ebx
           add  edx,30h     ;余数+30h变为对应的十进制ascll码
           push edx         ;低位入栈
           inc  di          ;位数+1
           mov  ecx,eax     ;把商放cx里用 jcxz跳转
           jcxz s5          ; 商0的时候跳转,说明该数已经全部转换为十进制且入栈
           jmp  s


    s5:    
           mov  cx,di       ;cx放一共有几位,循环计数
    s4:    
           pop  edx         ;之前进栈的,现在出来
           mov  ah,2h
           int  21h
           loop s4          ;循环直到cx=0
           mov  dl,0dh
           mov  ah,2h
           int  21h
           mov  dl,0ah
           mov  ah,2h
           int  21h
           pop  ecx
           RET
    OUTPUT ENDP
END START
END