2

私はアセンブリ言語が初めてです。小さなプログラムを書き始めました。「*」ピラミッドを出力するための基本的なループ プログラムを作成しました。しかし、プログラムは無限ループに入ります。以下にコードを貼り付けます。誰か助けてくれませんか?始める:

   mov ecx,2
   invoke StdOut, addr startProg

label_1:

   .while ecx > 0

   push ecx
       pop aInt

     .while aInt > 0
       invoke StdOut, addr star
       sub aInt, 1
     .endw

        dec ecx
    .endw

     ;invoke StdOut, addr newline


   jmp out_
out_:
   invoke ExitProcess, 0  

終了開始

4

3 に答える 3

3

Invoke は、__stdcall 呼び出し規約を介してメソッドを呼び出します。その規則の一部は、その呼び出しで EAX、ECX、および EDX が保持されないことです。これが、ECX および EAX レジスタがデクリメントせず、ループが停止する理由です。

于 2013-01-22T06:09:45.873 に答える
1

@SecurityMatt が述べたように、無限ループに陥る理由は、ecxへの呼び出しで の値が変更されるためStdOutです。
を使用してレジスタを保存し、次を使用pushして復元することで、これを回避できpopます。

.while ecx > 0
   push ecx
   pop aInt
   ; preserve state of `ecx`
   push ecx
   .while aInt > 0
     invoke StdOut, addr star
     sub aInt, 1
   .endw
   ; restore ecx
   pop ecx
   dec ecx
.endw

すべての汎用レジスタ値をスタックにプッシュ/ポップするためにpushadandを使用することもできます。popad

; push general-purpose registers values onto stack
pushad
invoke StdOut, addr star
; restore general-purpose registers
popad
于 2013-07-20T23:17:58.603 に答える
0

アセンブリ命令とマクロを混同している可能性があります。.while はアセンブリ命令ではなく、マクロです。「.」で始まるすべてのディレクティブで同じです。

于 2013-01-20T07:26:51.887 に答える