2011-11-14 40 views
0

我有一個關於asm(x86/GAS)程序的問題,它返回一個分段錯誤。 這是一個關於Fibonacci:我認爲algorith是確定:(僞代碼)asm program遞歸

fibo(int number){ 
    if (n < 2) 
     return number; 
    return fib(n - 1) + fib(n - 2); 

我不明白爲什麼會出現錯誤。 C程序調用asm函數。

下面是代碼:

fibo: 
    movl 4(%esp), %ebx #argument n in %ebx 
    cmpl $2, %ebx   # test: is n < 2 ? 
    jnl  recur   # no, recursion 

    jmp  quit    # yes : quit 

recur: 


    movl %ebx, %eax # get value of argument n 
    subl $1, %eax  # n-1 
    pushl %eax  # push n-1 
    call fibo  # recursive call : fib(n-1) 
    movl %eax, %edx # save result in %edx 
    movl %ebx, %eax # get value of argument n 
    subl $2, %eax  # n-2 
    pushl %eax  # push n-2 
    call fibo  # recursive call : fib(-2) 
    addl %edx, %eax # add fib(n-1) + fib(n-2) 

你能幫我找到哪裏是段錯誤?

謝謝!

PS:這裏是RET:

quit: movl %ecx, %eax #result in %ecx 
     ret 
+1

掛上,你寫了這段代碼,但是你不能在調試器中單步查找問題? –

+2

你似乎沒有正確設置函數的堆棧框架 - 我沒有看到'ebp'被調整到任何地方... –

+0

哎呀,這是什麼原因造成的?這個特殊的遞歸實現在堆棧上將非常困難。 –

回答

3
  1. 如何從你的函數返回?
  2. 您是否期望您的call能夠保存寄存器中的值?

答案將爲您提供解決方案。

1

正如其他人指出的,你不顯示你的ret指令,這很重要。另外,還可以保存edx中的中間結果。這是行不通的 - 隨後的遞歸調用也會這樣做,並會打破您在此調用級別的價值。您還需要將該中間值存儲在堆棧中。

+0

我存儲了中間值,但我不明白爲什麼我應該使用%ebp,而我已經使用% esp:複製堆棧?謝謝 – lilawood

+1

您不需要使用ebp設置顯式堆棧幀。您可以像使用esp一樣使用esp - 在開發過程中更容易出錯,就是這樣。 –

+0

感謝您的回覆 – lilawood