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

posted @ 2019-11-25 09:02  wawcac  阅读(...)  评论(...编辑  收藏