2012-10-12 114 views
-2

我的任務是編寫一個計算斐波納契數列前七個值的程序。給出的公式是:X86斐波納契程序

Fib(1) = 1, Fib(2) = 1, Fib(n) = Fib(n-1) + Fib(n-2) 

我相信這是一個函數,但我不明白如何將它合併到代碼中。我需要把這些值放在EAX寄存器中。我使用MASM沒有任何區別。任何提示?

+0

這可能是一個家庭作業,所以我會像這樣對待它。 – Wug

+1

從1開始的第7個斐波納契數是13,所以只是'mov eax,13',你就完成了。那,或者你沒有給出完整的要求。 – harold

+0

我寫了[另一個問題的幾個版本](http://stackoverflow.com/a/32661389/224132),其中包括一個展開的兩個版本,處理奇數和偶數輸入的開銷很小,一個版本它使用SSE向量,因此它可以在32位CPU上執行64位數學運算。有關有趣的斐波那契數學(例如計算O(log(N))時間內的Fib(N)的函數),請參見關於該問題的其他答案。 –

回答

6

我懷疑這是一個學術任務,所以我只想部分回答這個問題。

Fibonacci序列中正式對非負整數定義如下:

F(n) = n     | n < 2 
    = F(n - 1) + F(n - 2) | n >= 2 

這給:

n | F(n) 
    0 | 0 
    1 | 1 
    2 | 1 
    3 | 2 
    4 | 3 
    5 | 5 
    6 | 8 
    7 | 13 
etc etc... 

你可以只用幾個寄存器做,讓我們確定它們:

  • R n(請求的斐波那契nu的數量MBER)
  • ř F1(用於計算斐波納契數)
  • ř F2(也用於計算斐波納契數)
  • ř X(寄存器來保存返回值。可以與任何其他寄存器重疊)

R n作爲參數傳遞給函數。 [R F1應當從0開始,和R F2須從1開始

這就是我們要做的得到答案,通過程序分裂:

開始

  1. 初始化R f1爲0.
  2. 初始化R f2爲1.
  3. 繼續循環。

環路

  1. 減去2選自R Ñ
  2. 如果R n小於0,則跳轉到完成。
  3. 加上R F2至R F1,儲存中的R F1結果。
  4. 加上R F1至R F2,儲存中的R F2結果。
  5. 跳轉到循環。

完成

  1. 若R Ñ,1是假(暗示的是,R Ñ甚至)跳到FinishEven。
  2. 商店R f1作爲返回值。
  3. 退貨。

FinishEven

  1. 商店ř F2作爲返回值。
  2. 退貨。

跟蹤通過對R Ñ = 5:

  1. ř F1 = 0
  2. ř F2 = 1
  3. řÑ = R Ñ - 2 // R n = 3
  4. 試驗R Ñ < 0 //假
  5. ř F1 = R F1 + R F2 // - [R F1 = 0 + 1 = 1
  6. ř F2 = R F1 + R F2 // - [R F2 = 1 + 1 = 2
  7. 無條件跳轉到環路
  8. řÑ = R Ñ - 2 // - [R Ñ = 1
  9. 試驗R Ñ < 0 //假
  10. ř F1 = R F1 + R f2的 // - [R F1 = 1 + 2 = 3
  11. ř F2 = R F1 + R F2 // - [R F2 = 3 + 2 = 5
  12. 無條件跳轉到環路
  13. řÑ = R Ñ - 2 // - [R Ñ = -1
  14. 試驗R ñ < 0 //真
  15. 跳轉到完成
  16. 試驗R ñ & 1 //真
  17. ř X = R F2 // 5

我們表顯示了F(5)= 5,所以這是正確的。

+0

謝謝,有用但仍然不在我的水平。也許你可以用俗語來修改公式? – user1740117

+0

你給他們的小手指,他們會想要雙手...... – hirschhornsalz

0
TITLE Chapter 4 Exercise 6    (ch04_06.asm) 

Comment ! 
Description: Write a program that uses a loop to calculate the first 
seven values in the Fibonacci number sequence { 1,1,2,3,5,8,13 }. 
Place each value in the EAX register and display it with a 
call DumpRegs statement inside the loop. 

Last update: 05/02/2002 
! 
INCLUDE Irvine32.inc 

.code 
main PROC 
    mov eax,1 
    call DumpRegs 
    mov ebx,0 ; initial setup 
    mov edx,1 
    mov ecx,6 ; count 
L1: 
    mov eax,ebx ; eax = ebx + edx 
    add eax,edx 
    call DumpRegs ; display eax 
    mov ebx,edx 
    mov edx,eax 
    Loop L1 

    exit 
main ENDP 
END main