2016-03-28 26 views
-1

これを簡単に保つため、私は最初のMASM32プロジェクトを受け取りました。次のようになります: "1から46368までの最初の24フィボナッチ数を生成して表示するアセンブリプログラムを作成します。これが私の最初のプロジェクトであるので、私はこのコードをどのように始めるか書き込むかについて正直に考えていません。どんな助けでも大歓迎です。どうもありがとうございます。アセンブリ言語とフィボナッチ番号

+0

あなたはこれまでに何をしようとしましたか? –

+0

まず、番号を表示するプログラムを作成します。 –

+0

あなたは超簡単な方法で、最初の24個の数字を含むデータを作成して印刷することができます。 ;) –

答えて

0

fibunacciは通常、単純なループでそれを解決するように簡単ですが、再帰的に解決される傾向にあっている

すでにお使いの配列が24ワード大きくなることがわかっている


と初見で、それがどのように見える
あなたのループは24ステップになります

f(1)とf(2)は既に設定されていますが、少なくとも2つの要素が必要ですが、必要な要素の数は24ではなく22です。既に知っているものから始めましょう。

fib dw 24 dup (0) ; i don't know masm too well, this should create 24 words 
    mov word ptr[fib ],1 ; f(1) 
    mov word ptr[fib+2],1 ; f(2) 

    mov cx,22   ; this will be the loop counter 
l1: 
    ; add up the last 2 elements 
    dec cx 
    jnz l1 

これまでのところ大丈夫です。最後の2つの要素が格納されている2つのレジスタのBEGSを「最後の2つの要素を加算」し、必ずしもメモリから読み込む必要はありません。だから、AXとBX、AXを要素n-2に、BXをn-1に使ってみましょう。それらを追加し、結果を '次の'配列要素に格納します。アレイ用
が、それは合算した後、私たちが書いている一方で、DI(宛先インデックスは)私たちの最良の選択

fib dw 24 dup (0) ; i don't know masm too well, this should create 24 words 

calculate: 
    cld 
    mov word ptr[fib ],1 ; f(1) 
    mov ax, 1 
    mov word ptr[fib+2],1 ; f(2) 
    mov bx, 1 
    mov di, offset fib+4 ; does this work in MASM ? 

    mov cx,22   ; this will be the loop counter 
l1: 
    add ax,bx 
    stosw   ; write new element to array 
        ; note: this is equivalent to mov [di], AX and add si,2 

    dec cx 
    jnz l1 

で、SIおよびジを使用するのは素晴らしいことだ、我々は正しい値と斧とBXをロードする必要があります、f(n)とbxをf(n-1)で斧...配列から読み込むことでそれを行うことができますが、もっと詳しく見ると、AXはf(n)次のループではf(n-1)、BXはf(n-1)であり、次のループではf(n-2)となる。あなたは24個の要素が

PS

を計算してい::私はMASMがこれをコンパイルしますわからないんだけど、私は別のアセンブラを使用しています、与える

fib dw 24 dup (0) ; i don't know masm too well, this should create 24 words 

calculate: 
    cld 
    mov word ptr[fib ],1 ; f(1) 
    mov ax, 1 
    mov word ptr[fib+2],1 ; f(2) 
    mov bx, 1 
    mov di, offset fib+4 ; does this work in MASM ? 

    mov cx,22   ; this will be the loop counter 
l1: 
    add ax,bx 
    stosw   ; write new element to array 
        ; note: this is equivalent to mov [di], AX and add si,2 
    xchg ax,bx  

    dec cx 
    jnz l1 

らほらだから我々がしなければならないのは、単にそれらを交換されます私はヒントと私はそれを修正します

+0

プッシュ/ポップ?なんてこったい? 'xchg ax、bx'も同じことをします。ループエンドの状態では、カウンタにecxを無駄にする代わりに 'cmp edi、24 * 2 + OFFSET fib'や何かを行うことができます。もちろん、結果をまったく格納する必要はありません。ループ内から 'printf'を呼び出すのが最も簡単な方法です(呼び出し保持レジスタにループ状態を保つ)。そして、なぜあなたは16ビットポインタを使用していますか? OPは特に32ビットについて尋ねているようだ。 –

+0

また、フィボナッチはしばしば再帰的に実装されますが、それは再帰を教えるときに再帰関数の例としてピボットを選択するためです。再帰的に実装するのは難しく、*遅くなります。 O(n)の代わりにO(Fib(n))を使用すると、memoizationを使わない単純な再帰的な実装が可能になります)。2でアンロールするということは、データの移動をさらに少なくすることを意味します: 'add ebx、edi/print ebx /' add edi、ebx'/print ediはそのトリックを行います。とにかく、IMOの人々は、再帰が意味を持ち、ループにスタック状のデータ構造が必要な関数を使って再帰を教えるべきです。ツリートラバーサルは良い例です。 –

+0

私は "ポインタ"の比較を使うことができましたが、CXは必要ありません。レジスタをカウンターとして使うのが好きです。なぜそうでしょうか?これはもっと読みやすくなります。しかし、あなたは交換について完全に正しいです。私は指示を忘れてしまいます(あまりにも多くの命令セットはどの命令にどの命令が含まれているかを覚えていません)、私はそれを変更しました – Tommylee2k