0

こんにちは私はアセンブリに不慣れで、2部構成のプログラムを機能させるのに苦労しています。このx86アセンブリにはVisualStudioを使用しています。

パートI)私の最初の目標は、最大13までカウントし、そこに向かう途中で各値を追加することです。例:0 + 1 + 2 + 3 ... + 13=91。その合計を合計で保存したいと思います。

パート2)次に、2^0から2^6までの2の累乗でカウントアップしたいと思います。例、0、1、2、4、8、32、64。私はそう思っています*私はそうしていますが、私は行くにつれてそれぞれの値を保存していません。これらを連続したメモリ位置に保存したい。

私はこれまでにこれを持っています、

.586
.MODEL FLAT

.STACK 4096

.DATA
num1 BYTE 13          ;Initialize number to count to
totall BYTE 0         ;Total of all counted numbers
temp BYTE 0           ;Temp for loop adding

shiftme BYTE 1        ;Start of counting 2^0 so I can reach 2^6

.CODE
main PROC
;code here

increment:            ;Increment label
inc temp              ;Increment temp by 1
mov eax, temp
add totall, eax       ;Add temp+totall and store in totall
cmp eax, num1         ;Compare for jump
jne increment         ;Jump if not equal

;this part should store each value 1,2,4,8,32.. in consecutive memory locat
shiftallthethings:    ;Shift label
shl shiftme, 1        ;Shifting bits to the left one
cmp shiftme, 64       ;Comparing for the jump
jne shiftallthethings ;Jump if not equal to

ret
main ENDP
END

私が理解するのに役立つ質問。

  • 連続するメモリ位置に値を格納するにはどうすればよいですか?
  • ジャンプとラベルの説明を正しく使用していますか?
  • これらの問題を実行するには、eaxなどの特定のレジスタを使用する必要がありますか?なんで?

どんな助けでも大歓迎です、ありがとう。

4

1 に答える 1

2

まず、あなたの質問への回答として:

連続したメモリ位置に値を格納するにはどうすればよいですか?

MASM32 では、 (データ型が同じサイズである限り) movlikeを直接実行するか、データ ポインターを渡すことができます。mov sum_addr, eax私が書いた例では、へのポインタがtotal関数に渡されます。次に関数は、そのポインタが指すメモリ (つまり の内容total) に値を書き込みます。連続したメモリ位置の意味がよくわかりません。ポインター演算を意味する場合は、その例も示します。

ジャンプ命令とラベル命令を正しく使用していますか?

はい、それでよさそうです。私が使用している代替手段は、匿名ラベルです。これは、ラベルが些細で、かなり近くにある場合に適しています。それは個人的な好みです。レーベル名の方が適切だと思われる場合は、それも自由に使用してください。

これらの問題を実行するには、eax などの特定のレジスタを使用する必要がありますか? なんで?

MASM32 は Win32 の呼び出し規則 (stdcall) に従っているので、それも行うとよいでしょう。eaxレジスタの保存に関しては、すべての関数がレジスタを保存することが期待されていることを意味しecxますedx。4 バイト以上が必要な場合、戻り値はeaxor eaxandに格納されます。edx


あなたが書いたコードに関しては、異なるサイズのデータ​​型を互いに移動しようとするなど、いくつかの問題があります。たとえば、 を に移動する場合、byte最初dwordに同じサイズになるように拡張する必要があります。

mov eax, temp

temp長さは 1 バイトであるのに対し、eax4 バイトであるため、これはコンパイルされません。代わりに次のことができます。

movzx eax, temp

tempこれは、移動を行う前にゼロ拡張します。これは、いくつかのことを教えてくれるかもしれない、一緒に投げたコードです。マクロを使用しますが (まだそれらを学習する必要があるかどうかはわかりません)、それ以外の場合は、慣用的な MASM32 パラメーターの受け渡しと戻り値を示しています。

include \masm32\include\masm32rt.inc

.DATA

total DWORD 0         ;Total of all counted numbers

.CODE

; takes in address of total and writes the value there
sum PROC sum_addr:DWORD

xor eax, eax
xor ecx, ecx

  @@:
inc ecx
add eax, ecx
cmp ecx, 13
jnz @b

mov edx, sum_addr
mov dword ptr ds:[edx], eax
print ustr$(eax), 13, 10

mov edx, sum_addr
mov eax, dword ptr ds:[edx]
ret

sum ENDP

start:

push offset total          ; pass address of total
call sum
print ustr$(eax), 13, 10   ; demonstrating how to use return values

print ustr$(total), 13, 10 ; testing result got stored properly
ret

end start
END

コードは最適化されていませんが、簡単に理解できるはずです。できるだけ多くのレジスタを使用しようとしたことに注意してください (これは、十分な数のレジスタがある場合に常にメモリを処理するよりも効率的です)。

于 2012-03-26T20:54:27.860 に答える