2017-09-29 18 views
1

0からN-1までのすべての整数を出力するアセンブリでforループを作成しようとしました。なんらかの理由で、それが壊れて、無限ループが作成されます。なぜどんなアイデア?私はEAXの内容を破壊するのVisual Studio 2013 MASMアセンブリ言語でのループ

.data 
x   DWORD 0 
y   DWORD 0 


.code 
    main:nop 
     invoke version 
     invoke readInteger 
     add x, eax 
     cmp eax, y 
     je done 

    increase: 
     invoke writeInteger, y 
     inc y 
     cmp y, eax 
     jg increase 

    done: 
     invoke writeInteger, x 

     invoke ExitProcess,0 

    end main 
+6

使用VSのデバッガシングルステップへとレジスタを見て、あなたはなぜ知っているだろう。しかしおそらく 'writeInteger' clobbers' eax'は、ほとんどの呼び出し規則では普通です。 –

答えて

2

writeIntegerを使用していますので、あなたは容易にあなたが必要とするので、ループは動作しませんそれさえも修正してcmp y, eax

でそれを使用することはできませんY変数は、あなたがゼロでyを開始し、それをインクリメントするので、関係するすべての数字は(意志

xより小さいとき増加に戻ります入力がゼロの場合は、入力がの場合、と表示されるため、何も表示しないでください。すべて一緒に置く

が、これは解決策です:

invoke readInteger 
test  eax, eax 
jz  exitNow 
mov  x, eax    ;x=[1,2GB-1] 
increase: 
invoke writeInteger, y 
inc  y 
mov  eax, x 
cmp  y, eax 
jne  increase 
exitNow: 
invoke ExitProcess,0 
+0

ねえ、おかげで解決策がたくさんあります。 cmpとテストの違いは何ですか? eaxとeaxを常に等しくするべきではないので、exitにスキップしてください。 –

+0

@RomanProcházkaJr。 'test'命令は、そのオペランドに対してビット単位のAND演算を実行し、それに応じてフラグをセットします。この場合( 'test eax、eax')、デスティネーション・オペランドとソース・オペランドは同じであるため、' eax'がゼロであるかどうかを反映するゼロ・フラグが反映されます。代わりに 'cmp eax、0'' je exitNow'と書くこともできます。ただし、この代替方法では1バイトのコードを消費します。 – Fifoernik