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...
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
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?
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
«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
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
thanks for the help dednave, and the others guys. :U