2016-05-06 17 views
0

私はアセンブリ言語をかなり使い慣れており、このプログラムを理解しようとしています。ちょうど私がプログラムのポイントにいるかどうかを知りたい。このプログラムを修正するにはどうすればよいですか?アセンブリ言語x86 Irvine32

バイト配列内のすべての要素の合計を計算するループを作成します。結果を印刷します。ヒント:適切なレジスタに配列のサイズをロードします。配列の現在の要素のオフセットをロードし、ループの繰り返しごとにそれを変更します。

ここで私がこれまで持っているものです。

INCLUDE Irvine32.inc 

.data 
    val1 BYTE 1,2,3 
    counter = 0 
.code 

main PROC 

    mov ax, 0 

    mov ax, (LENGTHOF val1) 
    mov ax, OFFSET Counter 
    movzx ecx,ax 
L1: 
    add eax, val1[ecx] 
    inc eax 

loop L1 

    Call WriteDec 

exit 
END PROC 
    end main 
+1

_「このprを修正する方法ogram? "_どのように意図したとおりに動作しませんか? – Michael

答えて

2

あなたはあなたのコード内のいくつかのエラーがあります:あなたが繰り返しかなり無用である斧を設定し、次のシーケンスでは:

mov ax, 0       ; you set ax to 0 
mov ax, (LENGTHOF val1)   ; you set ax to 3 
mov ax, OFFSET Counter    ; you set ax to an address (and try to use a 16-bit register for a 32-bit address 

その後、あなたはこのオフセットを別のオフセットに追加してください。

movzx ecx,ax 
L1: 
    add eax, val1[ecx]    ; add offset(val1)[offset(Counter)] to offset(Counter) 

アドレスがどこにでもある可能性があるため、確実にメモリエラーが発生します。そして、あなたは、これが

inc eax       ; you probably confused this with a counter/index register 

オフセットその後、あなたがこれを使用しますが、後

loop L1       ; decrements ECX and loops if ECX != 0 

LOOP命令にECXにインデックスとしてmovzx ecx, axによってそこに置かECX、オフセット増加しますこれらのエラーをすべて修正すると、コードは次のようになります。

INCLUDE Irvine32.inc  
.data 
    val1 BYTE 1,2,3 
    counter = 0 
.code 
main:  
    xor eax, eax      ; 32-bit register for the sum 
    xor edx, edx      ; 32-bit register for the counter/index 
    mov ecx, LENGTHOF val1   ; number of entries in fixed size array in ECX as maximum limit 
L1: 
    movsx ebx, byte ptr val1[edx] ; extend BYTE at offset val1 + EDX to 32-bit 
    add eax, ebx      ; add extended BYTE value to accumulator 
    inc edx       ; increase index in EDX 
loop L1       ; decreases ECX and jumps if not zero 

    Call WriteDec     ; I assume this prints EAX 
    exit 
end main 
+0

** add eax、val1 [edx]; val1 + EDXのオフセット**これは無効な命令オペランドではありませんか?私はこれが問題を抱えているように感じます。 –

+0

はい。あなたは正しいです、私は配列がバイトサイズのことを忘れていました。それを反映するようにコードを修正しました。この場合、「MOVSX」は8ビットをメモリから32ビットレジスタ(符号付き)に移動します。 – zx485

+0

'inc edx/cmp edx、LENGTHOF val1/jle'でループすると、通常は呼び出されて保存される(' ebx')レジスタを壊さないようにすることができます。それはecxをmovsxのための傷として解放する。あるいは、逆の順序で配列にアクセスすることができますので、dec-and-branchループを使用することもできます。 (ただし、val1 - 1 [edx] 'を使用していますが、要素0..len-1ではなく1..lenです)。あるいは、 '-LENGTHOF val1'で始まるカウンターを使ってfowardをループさえ、ゼロに向かってカウントアップすることもできます。 'val1 + LENGTHOF val1 [edx]'か何かから読み込みます。 –

関連する問題