16位masm汇编实现记忆化递归搜索斐波那契数列第50项

.model small
;递归fib,使用压缩BCD码,小端派
.data
    
    y1 byte 6 dup(0)
    y2 byte 6 dup(0)
    vis byte 1,1,1,61 dup(0)                                    ;便于调试
    num byte 6 dup(0),1,5 dup(0),1, 5 dup(0), 300 dup(0)    ;di

.stack 4096

.code
main proc far
start:
    mov ax,@data
    mov ds,ax
    
    mov ax,50
    call fib
    

    mov bx,offset y1
    add bx,5
    mov cx,6
    output:
        mov dl,[bx]
        mov dh,dl
        push cx
            mov cl,4
            shr dl,cl;取出高四位
        pop cx
        or dl,30h
        mov ah,2h
        int 21h
        mov dl,dh
        and dl,0Fh;取出低四位
        or dl,30h
        mov ah,2h
        int 21h
        dec bx
    loop output

    
    mov ax,4c00h
    int 21h
main endp

fib proc near   ;从ax传参,保证ah为0,然后将计算得到的fib(al)写入表中,再写入y1,返回
    push ax     ;先备份一下  
    mov bx,offset vis
    xlat
    and al,al
    jnz returnresult    ;查表有结果,直接返回结果

    pop ax              ;vis数组置位
    push ax
    mov si,ax
    mov [bx+si],1

    pop ax
    push ax
    sub ax,2
    call fib                        ;求fib(n-2)
    mov bx,offset y1                    ;将fib(n-2)从y1转存到栈
    
    pop ax
    push ax
    push [bx]
    push [bx+2]
    push [bx+4]

    dec ax
    call fib
    mov bx,offset y1                    ;把y1 fib(n-1)的值加到y2上
    mov bp,offset y2
    pop ds:[bp+4]
    pop ds:[bp+2]
    pop ds:[bp]
    pop ax
    push ax

    mov cx,6
    and ax,ax;清空进位标识cf
    bcdadd:
        mov al,[bx]
        adc al,ds:[bp]
        daa
        mov ds:[bp],al
        inc bx
        inc bp
    loop bcdadd
    ;最高位应该没有进位了

    pop ax                          ;恢复参数
    mov bl,6
    mul bl
    mov bx,offset num               ;bx指向表
    add bx,ax
    mov bp,offset y2                ;bp指向算出来的y2
    mov di,offset y1
    mov si,0
    mov cx,3
    writenum:
        mov ax,ds:[bp+si]           ;bp默认ss
        mov [bx+si],ax              ;y2->num
        push bx
            mov bx,di
            mov [bx+si],ax          ;y2->y1
        pop bx
        add si,2
    loop writenum
    ret

    returnresult:                   ;将表中的答案弄到y1
    pop ax
    mov bl,6
    mul bl
    mov bx,offset num
    mov bp,offset y1
    add bx,ax
    mov ax,[bx+4]
    mov ds:[bp+4],ax
    mov ax,[bx+2]
    mov ds:[bp+2],ax
    mov ax,[bx]
    mov ds:[bp],ax
    ret
fib endp


end start

猜你喜欢

转载自www.cnblogs.com/wawcac-blog/p/11925825.html