2

私はアセンブリに不慣れで、10,000までカウントして終了するプログラムを作成しようとしています。私はfasm`を使用しています

    include 'include/win32ax.inc'

   .data

   inchar     DB ?
   numwritten DD ?
   numread    DD ?
   outhandle  DD ?
   inhandle   DD ?
    strFormat  DB "Number %d ",0
   strBuff    RB 64

   .code
     start:


   ;set up console
    invoke  AllocConsole
    invoke  GetStdHandle,STD_OUTPUT_HANDLE
    mov [outhandle],eax
    invoke  GetStdHandle,STD_INPUT_HANDLE
    mov [inhandle],eax

    ;loop starts here
    mov eax, 0
    LoopStart:
    add eax,1



    invoke wsprintf, strBuff, strFormat, eax   ;convert number to String.

    ;the number eax is now in string form in strBuff

            ;find out the string length of strBuff
    mov ecx,-1
    mov al,0
    mov edi,strBuff
    cld
    repne scasb
    not ecx
    dec ecx
         ;ecx is now the length.



    invoke  WriteConsole,[outhandle],strBuff,ecx,numwritten,0   ;write to console
    ;loop
    cmp eax, 10000;loop compare
    jne LoopStart;jump to start of loop

    invoke  ReadConsole,[inhandle],inchar,1,numread,0 ;give the user a chance to read console output before exit
    invoke  ExitProcess,0


     .end start                                                                                                          `

ナンバー1ナンバー2ナンバー3などを印刷することになっていますが、代わりにナンバー2ナンバー2ナンバー2ナンバー2ナンバー2などをしばらく印刷してから、ユーザーの入力を待たずに終了します。私のコードの何が問題になっていますか?

編集:私はそれを動作させました!作業コード:

 include 'include/win32ax.inc'

    .data

       inchar     DB ?
       numwritten DD ?
        numread    DD ?
      outhandle  DD ?
        inhandle   DD ?
         strFormat  DB "Number %d ",0
          strBuff    RB 64
         number DD ?

          .code
        start:


          ;set up console
         invoke  AllocConsole
          invoke  GetStdHandle,STD_OUTPUT_HANDLE
             mov [outhandle],eax
           invoke  GetStdHandle,STD_INPUT_HANDLE
            mov [inhandle],eax

         ;loop starts here
           mov eax, 0
         LoopStart:
              add eax,1
            mov [number],eax
             mov edi, eax
             push eax
             invoke wsprintf, strBuff, strFormat, edi  ;convert number to String.
            add     esp, 4 * 3


           pop eax
           ;the number eax is now in string form in strBuff

             ;find out the string length of strBuff
             mov ecx,-1
             mov al,0
              mov edi,strBuff
               cld
              repne scasb
             not ecx
              dec ecx
                ;ecx is now the length.


              push eax
       invoke  WriteConsole,[outhandle],strBuff,ecx,numwritten,0   ;write to console
    pop eax
    ;loop
    mov eax, [number]
    cmp eax, 10000;loop compare
    jne LoopStart;jump to start of loop

    invoke  ReadConsole,[inhandle],inchar,1,numread,0 ;give the user a chance to read console output before exit
    invoke  ExitProcess,0

.end start

4

2 に答える 2

3

ライブラリ関数は、独自のニーズに合わせてレジスタを使用し、それらを元の値に復元しません。価値を失いたくない場合は、記憶に留めておく必要があります。最も簡単な方法は、スタックを使用することです。

push eax ; put value of eax on the top of stack

pop eax  ; remove value from top of stack, save it in eax.
于 2013-03-16T15:52:16.157 に答える
1
于 2013-03-16T16:56:42.137 に答える