1

Windows Vista で実行している masm32 でループを作成しようとしていますが、この方法で実行したところ、実際にループが終了してもクラッシュし、明らかな理由がわかりません...アイデアはありますか?

.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

.data
ProgramText db "Looping!", 0

.data?
loop_stopper   dd      ?

.code
start:

mov loop_stopper,2

loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper                 
jg loop_start

end start

編集

やりました

invoke StdOut, offset ProgramText

それでも壊れる…

4

3 に答える 3

5

アプリケーションを終了するには、「出口」が必要です。また、私の個人的なスタイルは、すべてをサブルーチン内に配置することですが、それは私だけです。

何かのようなもの:
.code

start:

call main
inkey        
exit

main proc

mov loop_stopper,2
loop_start:

invoke StdOut, addr ProgramText
cmp loop_stopper, 0 
dec loop_stopper
jg loop_start
ret

main endp

end start

于 2009-02-10T05:01:22.963 に答える
2

あなたの指示の順序が間違っているようです。比較、デクリメント、条件付きジャンプを行います。比較からのフラグ値は、デクリメントによって変更される可能性があります。

  loop_start:

  invoke StdOut, addr ProgramText
  cmp loop_stopper, 0 
  dec loop_stopper
  jg loop_start

  ret

アセンブリ プログラミングを行っていたときは、次のようにしました。カウンターをデクリメントし、ゼロ以外の場合はループします。

 loop_start:

  invoke StdOut, addr ProgramText

  dec loop_stopper
  jnz loop_start

  ret

もちろん、プロセッサーによっては、ループ変数をレジスターに入れることもできます。これにより、単一の命令を使用してデクリメントとループを行うことができます。(たとえば、Z80 の 'djnz' 命令。'B' レジスタがベルを鳴らしているように見えますが、それが実際にどのレジスタであったかは覚えていません)。

また、他の人が示唆しているように、メモリ空間をクリーンアップしていないようです。ほとんどのプログラムは、実際にはコードへの「呼び出し」です。したがって、オペレーティング システムの呼び出し部分に適切な "RETURN" を実行できるように、コードとスタック ポインターを保持する必要があります。そうしないと、'RETURN' によって、たまたまスタックの一番上が指している場所に移動する可能性があり、通常は悲惨な結果を招きます。

于 2009-02-10T06:23:40.283 に答える
1

ClubPeteyは正しいです。MASMは、コードのエピローグを生成しません。したがって、プロセッサは、最後に書き込まれた命令の背後で検出したものの実行を続行します。exitは、オペレーティングシステムにプログラムの実行を停止するように明示的に要求します。

于 2009-02-10T04:56:50.773 に答える