2016-10-11 18 views
-3

私は自分の時間にアセンブリ言語を学び、次の問題を解決しようとしています。私はコードを書いたが、うまくいかない。 Fib(1)= 1、のFib(2)= 1、のFib(N)=のFib:アセンブリ言語コードの問題

以下の式によって記述フィボナッチ数列の最初の7つの値を計算するためにループを使用するプログラムを書きます(n-1)+ Fib(n-2)である。

このプログラムはアセンブリ言語で書かれています。アセンブリ言語でコードを記述する手順として、プログラムテンプレートのコメントを使用します。私は、このプログラミング・ロジック次のプログラムは、アセンブリ言語で書かれたい:私は次のように私のコードを編集した

ExitProcess PROTO 

.data 

numbers DWORD 10 DUP (?) 

.code 
main PROC 
    mov ebx,0 
    mov edx,1 
    mov numbers,edx 

    mov ecx,6 
    mov esi,4 

L1: 
    mov eax,ebx 
    add eax,edx 
    mov esi,OFFSET numbers 
    mov [esi],edx 
    mov eax,ebx 
    add eax,edx 
    mov edx,ebx 
    mov eax,edx 
    add esi,4 
Loop L1 

    call ExitProcess 
main ENDP 
END 

.data 
;declare an array 
.code 
main proc 
;move 0 into ebx to initialize 
;move 1 into edx to store the first Fib value 
;move edx into an array ; store the first Fib value 

; prepare to loop 
; loop counter for 6 more values 
; move esi,4 
; array index for 3rd Fib value 

L1: 
;move ebx into eax 
;add edx and eax 
;move edx into the array of esi 
; eax = ebx 
; eax = eax + edx 
; store the Fib value 
;move edx into ebx 
; prepare for next iteration 
;move eax into edx 
;add 4 to esi 
;Loop L1 

invoke ExitProcess,0 

私のコード

ExitProcess PROTO 

.data 

numbers DWORD 10 DUP (?) 

.code 
main PROC 
    mov ebx,0 
    mov edx,1 
    mov numbers,edx 

    mov ecx,10 
    mov esi,4 
    mov esi,OFFSET numbers 

L1: 
    mov eax,ebx 
    add eax,edx 
    mov [esi],edx 
    mov ebx,edx 
    mov edx,eax 
    add esi,4 
    Loop L1 

    call ExitProcess 
main ENDP 
END 

ときIコードをステップ実行すると、eaxレジスタとedxレジスタはフィボナッチシーケンス値1,2,3,5,8,13などを表示します。しかし、コードはeaxレジスタまたはedxレジスタ値を数値aに格納しますか?ラリー?もしそうでないなら、私はこれをどうやって行うのか?

これは有効なコード行ですか?数値配列にedx値を格納していますか?

mov numbers,edx 

数値配列にeax値またはedx値を格納するにはどうすればよいですか?

+0

スタックオーバーフローは、「please give me te codez」のようなウェブサイトではありません。 – fuz

+1

次回は、コードを記入するときにコメントを削除しないでください。たぶんあなたは少しコンパクトにすることができますが、参照とデバッグのためにそれらを保持します。 – Ped7g

+0

'mov番号、edx'はMASM(TASMもMASMをエミュレートする)で有効です。 'mov DWORD PTR [ds:OFFSET numbers]、edx'(それを正確に記述する冗長な技術的方法)にコンパイルされます。ソースの読者から '[]'(メモリアクセス)が隠れているので、妥当ですが、混乱し、醜いです!問題のあなたの新しい編集は、デバッグしてメモリと 'esi'値を見て、' OFFSET数値 'と比較すれば、ちょっとしたキャッチでほぼ正確です。あなたはすぐにそれを修正します。 – Ped7g

答えて

0

あなたのコード内の問題のいくつか:あなたは要素「numers [0]」すべての時間を上書きされますので、

mov esi,OFFSET numbers 
mov [esi],edx 

これは、先にそれぞれのesiを初期化しますが、書き込み。

mov eax,ebx 
add eax,edx 
mov edx,ebx 
mov eax,edx 

これはあまり意味がありません...まず、あなたは(EAXは、すでに前の行から、その値が含まれています)eax = ebx+edx ...二時間を計算します。 mov ebx,edx mov edx,eax

次に、あなたはおそらくそれをのような他の方法で回避し、やってみたかった(。つまり、あなたはEAXとEDXの両方にEBXをコピー) eax = edx = ebx;を行います。

元のコメントから「move esi、4」と表示されても意味がありません。add esi,4と入力するとのアドレスがすでにesiにあると思います(次のコードのように)。

しかし、あなたはどのアドレスが分かっていないかのように見えるので、「Fib値を保存する」に何度も何度もアドレスをロードします。全体のポイントは、アレイの先頭にesiを1回だけ設定し、各書き込み後に次の空き領域を指すようにポインターを更新することです。


いくつかのデバッガを取得し、それがあなたに慣れるだろうまで、彼らが何をすべきか、各命令の記述と比較し、各命令の後のステップで、レジスタとメモリのステップを見て開始する全体的に、それがコードから見えますそれらの命令が実際に何をするのかわからない。nは、純粋な紙式の作品(「F(N)= F(N-1)+ Fを(やっているどのように多くの指示に注意してください。また

mov esi,OFFSET numbers ; esi = target array address 
    mov ecx,7 ; produce seven numbers 
    xor ebx,ebx ; ebx = 0 F(-1) 
    mov edx,1 ; edx = 1 F(0) 
    jmp store_number 
loop1: 
    add ebx,edx ; ebx: F(n) = edx: F(n-1) + ebx: F(n-2) 
    xchg ebx,edx ; ebx: F(n-1), edx: F(n) 
store_number: 
    mov [esi],edx ; array_pointer[0] = F(n) 
    add esi,4  ; ++array_pointer 
    loop loop1 

:今


とはこのことを理解しよう-2)」)と「7個の数字」と、そのことをサポートするだけの命令がいくつあるのでしょうか?あなたは同意しないかもしれませんが、私はそのことを言うでしょう。 50%は "サポートクラフト"、そのほとんどは直接紙 - >コードの書き換えです。

アセンブリを学ぶときは、式レベルで達成したいことを最初に明確にしてから、を実行してください。 ...絶対に必要な場合にのみサポートコードを追加してください。それは良いアイデアのように見えるか、それ以前にそれを書いたので、ランダムな指示を書いてはいけません。指示は "あなたが望むものを何かする"か、それをカットするかのいずれかです。コメント


編集:記号 "数字" の

mov esi,OFFSET numbers店舗の住所esiに。 numbersを​​またはDWORDと宣言しても、割り当てられたメモリの最初の場所(最初のバイト)のアドレスポイントは重要ではありません。

バイト/ dword/dupは十分な総容量を確保するために重要ですが、アドレス自体( "シンボル")には影響しません。

mov [aaa],vvvは、アドレス "aaa"のメモリに値 "vvv"を格納します(可能な組み合わせを確認するための確認の手引き)。

だからmov esi,OFFSET numbersの直後にmov [esi],edxは "numbers [0]"にすべての値を格納します。デバッガを見て、esiが毎回それをリセットしているところをmov esi,OFFSET numbersとします。

と(MASMの癖モードをエミュレートするときとTASM)店舗のみMASMで「数字」の配列にその値を、気まぐれ構文mov numbers,edxを使用しないでください、適切なインテルでは、ポインタ/アドレスの[]信号のデリファレンスの使用を構文命令がレジスタ/即値のみで動作するかどうか、またはメモリにアクセスするかどうかを知るために、ソースを読み取る間に簡単です。 (lea reg,[address]は例外で、メモリにアクセスせず、アドレスを計算するだけです)。 NASMではmov numbers,edxはまったくコンパイルされず、mov edx,numbersは配列から最初の値をロードするのではなく、アドレス自体(MASM/TASMではシンボルの前にOFFSETを書く必要があります)をロードします。

だから

「コードストアに数字の配列のEAXレジスタの値をしますか?」

いいえ、最初にnumbers[0]の値を上書きします。

+0

私は次の私のコードを編集した: – ISM34

+0

のExitProcess PROTO .dataの 番号DWORD 10 DUP .CODE メインPROC \tのMOV EBX、0 \tのMOV EDX、1つの \t楽章番号、EDX(?) \t MOV ECX、10 \t MOV ESI、4 L1: \tのMOV EAX、EBX \tがEAXを追加し、EDX \t MOV ESI、オフセット番号を \t MOV [ESI]、EDX \t MOV EBX、EDX \t MOV EDX、EAX \tは、4 \tループL1 \tコールのExitProcess 主ENDP ENDをESIを追加 – ISM34

+0

ときIコードをステップ実行すると、eaxレジスタにフィボナッチのシーケンス値が表示されます:1,2,3,5,8,13など。ただし、コードはeaxレジスタの値をnumbers配列に格納しますか?もしそうでないなら、私はこれをどうやって行うのか? – ISM34