2011-11-14 17 views
0

私は、セグメント化エラーを返すasm(x86/GAS)プログラムに関する質問があります。 それはフィボナッチについてです:私はalgorithはOKだと思い:(擬似コード)asmプログラムでの再帰

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にaddの中間結果を保存します。それはうまくいかないでしょう - それに続く再帰的な呼び出しもそれを行い、この呼び出しレベルで持っていた価値を奪うでしょう。その中間値もスタックに格納する必要があります。

+0

中間値を保存しましたが、なぜ%ebpを使用するのか分かりません。 esp:スタックを複製する? thanks – lilawood

+1

ebpを使用して明示的なスタックフレームを設定する必要はありません。 espを使用することができます。開発中にエラーが発生しやすくなります。それだけです。 –

+0

ご返信ありがとうございます – lilawood