The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: WYVERN666 on April 14, 2011, 05:56:27 AM

Title: learning loops...
Post by: WYVERN666 on April 14, 2011, 05:56:27 AM
Hello all community!. I am learning looping instructions, so mi idea was looping 10 times showing in each iteration a MessageBox with the actual iteration number, here is mi last code...


.486p
.model flat,STDCALL

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

.data
a BYTE 'Iteration Number',0
b BYTE 'Title',0

.code
do:
         Xor ECX,ECX
         Add ECX,10
         
         miloop:
                  CALL msg   ; without this call the code runs fine...
         
                  DEC ECX
                 
                  TEST ECX,ECX
         JNE miloop
         
         push 0
         call ExitProcess
         
         msg:
         invoke MessageBox,NULL,addr a ,addr b, MB_OK
         ;first thing, im using "addr a" because i dont know how to get the ECX value to show in the MessageBox
         ret
         
end do


But big problem is that loop never end, actually y debugged the app and the code nevers return from the first INVOKE MessageBox to the original loop.
So im missing something important should know...
Title: Re: learning loops...
Post by: dedndave on April 14, 2011, 06:44:24 AM
1) the MessageBox call destroys the contents of ECX
so, use PUSH and POP to save it across the call

2) when you DEC ECX, the DEC instruction sets the zero flag if the result is zero
so, there is no need for TEST ECX,ECX
Title: Re: learning loops...
Post by: WYVERN666 on April 14, 2011, 02:44:18 PM
thanks dedndave, now is fixed:

...

do:
         Xor ECX,ECX
         Add ECX,15       
         
         miloop:
                  CALL msg
         
                  DEC ECX           
         JNE miloop
         
         push 0
         call ExitProcess
         
         msg:
         PUSH ECX
         invoke MessageBox,NULL,addr a ,addr b, MB_OK
         POP ECX
         RET             
end do


The remaining thing is how to show the ECX value in the message box?
Title: Re: learning loops...
Post by: qWord on April 14, 2011, 02:47:46 PM
Quote from: WYVERN666 on April 14, 2011, 02:44:18 PMThe remaining thing is how to show the ECX value in the message box?
include \masm32\macros\macros.asm
...
invoke MessageBox,NULL,str$(ecx) ,0, MB_OK
Title: Re: learning loops...
Post by: RuiLoureiro on April 14, 2011, 03:05:03 PM
«first thing, im using "addr a" because i dont know how to get the ECX value to show in the MessageBox»

Convert ECX to ascii and show that ascii string


.586
.model flat, stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\masm32.inc
include     \masm32\include\user32.inc

includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\masm32.lib

.data
a      db 'Iteration Number',0
b      db 'Title',0

.code
do:
         mov    ecx, 10         
         miloop:
                  call   msg
         
                  DEC    ECX
                  jnz    miloop
         
         invoke     ExitProcess, 0
;***---         
msg     proc
        push    ecx
         invoke MessageBox,NULL,addr a ,addr b, MB_OK
         ;first thing, im using "addr a" because i dont know how to get the ECX value to show in the MessageBox
        pop     ecx
        ret
msg     endp
         
end do

Title: Re: learning loops...
Post by: dedndave on April 14, 2011, 03:13:13 PM
a couple finer notes...
we tend to write functions allowing EAX, ECX, and EDX to be trashed, sometimes returning values
so - i would move the PUSH/POP instructions to the loop

also, the DEC ECX/JNZ method of terminating a loop is great when speed is essential
however, this is a good example of a case where speed is not important
i would use the LOOP instruction instead, saving a couple bytes
it isn't important, but you can learn the difference and develop good habits
miloop: push    ecx
        call    msg
        pop     ecx
        loop    miloop

then, remove the PUSH/POP from the msg function

of course, the CALL could be eliminated altogther by placing the MessageBox inside the loop
but, i think that is part of what you were trying to do to begin with
Title: Re: learning loops...
Post by: WYVERN666 on April 14, 2011, 06:24:38 PM
thanks for the help dednave, and the others guys.  :U