omarek / drobnosti / fibonacci-asm

Fibonacciho čísla v jazyce symbolických instrukcí

Napsáno 7–8. dubna 2024 pro CISC instrukční sadu rodiny x86.

Řešení rekurzí (z principu neefektivní)

section .text
main:

	push 22 ; vstup, 22 => 17711
	call fibonacci
	add esp, 4

	; eax == 17711

	ret

; uint32_t fibonacci(uint32_t n) (navrat v eax)
fibonacci:
	push ebp
	mov ebp, esp
	push ebx
	push ecx

	mov ebx, [ebp+8]

	; n == 0 => return 0
	cmp ebx, 0
	jne .notZero
	mov eax, 0
	jmp .return
	.notZero:

	; n <= 2 => return 1
	cmp ebx, 2
	ja .aboveTwo
	mov eax, 1
	jmp .return
	.aboveTwo:

	; return f(n-2) + f(n-1)

	; ecx = fibonacci(n-1)
	dec ebx
	push ebx
	call fibonacci
	add esp, 4
	mov ecx, eax

	; eax = fibonacci(n-2)
	dec ebx
	push ebx
	call fibonacci
	add esp, 4

	add eax, ecx

	.return:
	pop ecx
	pop ebx
	mov esp, ebp
	pop ebp
	ret

Iterativní řešení

section .text
main:

	push 22 ; vstup, 22 => 17711
	call fibonacci
	add esp, 4

	; eax == 17711

	ret

; uint32_t fibonacci(uint32_t n) (navrat v eax)
; nejvyssi vstup pro ktery procedura funguje jest 46
fibonacci:
	push ebp
	mov ebp, esp
	push ecx
	push ebx

	mov ecx, [ebp+8]

	; n == 0 => return 0
	cmp ecx, 0
	jne .notZero
	mov eax, 0
	jmp .return
	.notZero:

	; n == 1 => return 1
	cmp ecx, 1
	jne .notOne
	mov eax, 1
	jmp .return
	.notOne:

	mov eax, 1
	mov ebx, 1

	.loop:
		; loop cond
		cmp ecx, 2
		jna .loopEnd

		; loop body
		add ebx, eax
		xchg eax, ebx

		; loop inc
		dec ecx
		jmp .loop
	.loopEnd:

	.return:
	pop ebx
	pop ecx
	mov esp, ebp
	pop ebp
	ret