2016-12-07 2 views
0

現在、私はアセンブリ言語(Motorola 68K Assembler)コースに登録しています。私は、最大30のフィボナッチ数の結果を印刷するプロジェクトがあります。たとえば、ユーザーが4を入力すると、結果は3になります(これは前の2つの数値の合計であるためです) )。しかし、私のメインプログラム(prog4.s)は継続的に0を出力します。問題は再帰的メソッドのロジックと何か関係がありますか?問題は他の場所にあるのでしょうか? FIBにコメントアウトアルゴリズム:ここでは、再帰的な方法の私のコード(fib.s)アセンブリ言語再帰:結果は常にゼロを出力します。再帰的方法で論理を発行するか?

* fib.s 
* long fib(int n) { 
*  if(n==0) { 
*  return 0; 
*  } 
*  else if(n==1) { 
*  return 1; 
*  } 
*  return fib(n-1) + fib(n-2); 
* } 

ORG $7000 

fib: 
    link  A6,#0 
    movem.l D1-D2,-(SP) 
    move.w 8(A6),D1 
    TST.w  D1 
    BNE  next 
    BRA  out 

next: 
    cmpi.w #1,D1 
    BNE  recurse 
    add.w  #1,D0 
    BRA  out 

recurse: 
    move.w D1,D2 
    subq.w #1,D1 
    move.w D1,-(SP) 
    JSR  fib 
    move.w D0,D1  * save copy of fib(n-1) 

    adda.l #2,SP 

    subq.w #2,D2 
    move.w D2,-(SP) 
    JSR  fib 
    add.w  D2,D1 
    add.w  D1,D0  * return fib(n-1) + fib(n-2) 

    adda.l #2,SP 

out: 
    movem.l (SP)+,D1-D2 
    unlk  A6 
    rts 

    end 

ここで注意すべきfib.s

fib: EQU $7000 
start: initIO 
setEVT 

lineout  title 
lineout  prompt 
linein  buffer 
cvta2  buffer,D1 

* Place parameter on the stack and move the stack pointer 
move.w  D1,-(SP) 

*Jump to the fib subroutine 
JSR   fib 

*Pop starting parameter off the stack 
adda.l  #2,SP 

cvt2a  buffer,#6 
stripp  buffer,#6 
lea   buffer,A0 
adda.l  D0,A0 
clr.b  (A0) 
lineout  answer 

break 

prompt:  dc.b 'Enter a number between 1 and 30: ',0 
answer:  dc.b 'The Fibonacci number is: ' 
buffer:  ds.b 80 
     end 

何かを呼び出すプログラムのための私のコードがあるです。私は使用する必要があります。どんな助けやアドバイスも大歓迎です。

+1

デバッガでコードをシングルステップ実行しようとしましたか? 68kシミュレータにはデバッガが内蔵されていると仮定します。これは、asm開発に不可欠なツールであるためです。 –

+0

マイナーコードの最適化では、 'n == 0'または' n == 1'をチェックするのではなく、 '(n <2)return n; 'とすることができます。 –

+0

@FrankC、ただし、fib.sでコメントアウトされたアルゴリズムは、このプロジェクトで使用する必要があります。 –

答えて

5

プログラムはほぼ正しいです。
問題は再帰のロジック内にはありません。それは、それぞれの呼び出しで計算された値を返す方法です。
デバッガを使用していくつかのトレースセッションを実行すると、問題を特定するのに役立ちます。

私はあなたにヒントを最初に教えています。これらの行

add.w  D1,D2  *fib(n-1) + fib(n-2) 
add.w  D2,D0  *add fib(n-2) 

コメントは何を言っていません。
D2D1fib(n-1)D0ので、最終結果はfib(n-1) + fib(n-2) + n - 2あるfib(n-2)での保持、n-2を保持しています。 ADD.W D1, D0に置き換えてfib(n-1) + fib(n-2)を返すだけです。

の2つのがあり、他のミスがあり、まだあなたは、他の2例(のn = 0のn = 1)の値を返す方法インチ

は、私が自分でfib(0)fib(1)への呼び出しをデバッグするEasy68kが付属してい68Kシミュレータを使用しようとするあなたを示唆して強く
重要なアドバイス:シミュレーションを開始する前にD0にランダムな値(例:$ 55555555)を設定し、F7を使用して実行をトレースします。

あなたが他のミスを見つけることに失敗した場合は、ここで彼らは

N = 1の場合に1を返すために使用される命令がD0の以前の値に依存ADD.W #1, D0です。
MOVE.W #1, D0である必要があります。
n = 0の場合、D0を変更せずにoutに分岐する場合は、D0をゼロに設定する必要があります。
MOVE.W #0, D0のようなものや別のゼロ化イディオム。

+0

こんにちは@Margaret Bloom、私は正常に私のコードにあなたの訂正を追加することができました。私が編集して以来、私の元の投稿に修正が表示されるはずです。しかし、私のプログラムはまだゼロを印刷しています。サブルーチンを呼び出すコードを元の投稿にも追加しました。戻り値(D0に配置する必要があります)へのアクセスに問題があると思いますか? –

+1

@ChristopherMoussaあなたのプログラムは、更新された質問からそのまま動いて正しく動作します。私は 'move.w#11、 - (SP)'/'jsr fib'を使ってSIM68Kでテストし、' D0'に89を返します。私は 'linein'と' cvta2'が何であるか分からないので、それらが正しく使われているかどうかチェックしたいかもしれません。最後に、質問には歴史的価値があります。元の問題点を示すために、変更をロールバックする必要があります。 –

+0

これを私のシミュレータで正常に実行することもできました。私は問題が私の登録の使用の中で嘘をついたことを発見しました(これは私の答えで説明されています)。ご協力ありがとうございました! –

0

この問題は、呼び出し側のプログラムprog4.sにあります。値を正しく読み込みましたが、間違ったレジスタをスタックに渡していました。マクロラインは、D1ではなくD0に2の補数の整数を格納します。あなたがそれを渡す前にD1にゼロが入っていたので、毎回ゼロを返していました。これは、呼び出し元プログラムの正しいコードは次のようになります。

fib: EQU    $7000 
start: initIO     * Initialize (required for I/O) 
     setEVT     * Error handling routines 
*  initF     * For floating point macros only 


lineout   title 
lineout   prompt 
linein   buffer 
cvta2   buffer,D0 


* Place parameters on the stack and move the stack pointer 
move.w   D0,-(SP) 


* Jump to the fib subroutine 
JSR    fib 


* Pop starting parameters off of the stack 
adda.l   #2,SP 


cvt2a   buffer,#6 
stripp   buffer,#6 
lea    buffer,A0 
adda.l   D0,A0   * Sets A0 to the address of D0 
clr.b   (A0) 
lineout   answer 


break       * Terminate execution 
* 
*---------------------------------------------------------------------- 
*  Storage declarations 


title: dc.b 'Program #4, Christopher Moussa, cssc0702',0 
prompt: dc.b 'Enter a number between 1 and 30: ',0 
answer: dc.b 'The Fibonacci number is: ' 
buffer: ds.b 80 
    end 
関連する問題