Hi , I am new in asm and I have a question about "loop".
I have made two examples, and in both versions the loop doesn't terminate!! Why ?

Example 1:#

.model flat,stdcall
option casemap:none

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

MsgBoxCaption db "FirstProg",0
MsgBoxText db "MessageBOX!",0


mov ecx, 10

invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
loop countdown

invoke ExitProcess, NULL
end start

Example 2:#

.Model Flat ,StdCall
option casemap:none

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

mb_ok equ 0
hWnd equ 0
lpText equ offset text
lpCaption equ offset caption


text db "FirstProg",0
caption db "Hello",0


mov ecx, 3


push mb_ok
push lpCaption
push lpText
push hWnd
call MessageBoxA

loop loopcount

CALL ExitProcess

End Main

Please help me

Posted on 2004-05-28 17:22:47 by FinalbrainXP
In the first sample code the problem lays in the fact that your call the the MessageBox() modifies value stored in the ECX register thus it will never reach 0.

You need to preserve the value which can be done in a few ways, for example, you can add push ecx bedore the function call and pop ecx after.
Posted on 2004-05-28 17:36:48 by Milos
Thank you very much :)

That means that MessageBox modifies itself the value of ecx or the invoke funktion ?
Posted on 2004-05-28 18:33:44 by FinalbrainXP
It's the MessageBox that modifies ECX and other registers too.

It's is only safe (well in most cases) to say that only EBX, ESI and EDI are preserved, and these registers should be preserved in your procedures as well (or later you might encounter some crashes).

For example if you make a procedure MyFunc PROC you should do it like

MyFunc PROC USES ebx esi, Parameter1 :DWORD etc...
This way EBX and ESI (but not EDI) will be preserved. If you want to use EDI in your proc and want it preserved then you simple add EDI to the list above.

When you call or invoke any API (MessageBox and it's friends) you should expect that registers (including the flag register) will change. So if you need some data that you stored in a register better push/pop it or save it somewhere else in the memory before you make your call.
Posted on 2004-05-28 19:01:40 by Milos
You should follow that, also note that invoke is a secuence of pushes and sometimes lea, followed by a call to the target memory respective function. Then no, the functions of the API do what Milos say about the preservation and trashing of register, not invoke by itself, invoke is a way of do a call.

Have a nice day or night.
Posted on 2004-05-28 19:26:43 by rea
Thanx for that detailed answer..good support *lol

I want learn much about Assembler..and if I am one day good, i try to help
you ;-)
Posted on 2004-05-28 20:02:32 by FinalbrainXP
Remember that 'loops' tend to be slow, and I personally try to avoid them! I would do something like this:
 push ebx

mov ebx, 10
invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
dec ebx
jnz countdown
pop ebx

The 'dec' instruction, decrements ebx and at the same time sets the zf (zero flag), we need no additional testing, we can then immeditately do a jump. Also, some processors are faster using 'sub ebx, 1'. Note that, if not already used in your code, ebx will be preserved 'automatically' if used by MessageBox (or another API!) This is 'hopefully' better than pushing popping ecx every time you call MessageBox, imagine you loop 1000 times, that's 1000 pushes and pops (2000 instructions). With the method above, you only have 1 push, and 1 pop because they are outside your loop!

Posted on 2004-05-31 05:14:56 by SubEvil
Oh yeah, better make the delay between the message boxes as small as possible so the user won't get frustrated and bored during those nanoseconds :P
Too bad it increases the time needed to download the program off the internet by a whopping 178 ms on a typical modem connection...
You can reduce the code size by 3 bytes if you replace the mov ebx,10 with push 10 / pop ebx, which shaves off over half a millisecond from the transfer time! Every time you do this, everyone who downloads the program saves about 2*10^-5 cents in phone bills.
Posted on 2004-05-31 05:46:43 by Sephiroth3
I was recommending 'general' loop design. Not for displaying a messagebox 2000 times! The content of the loop is generally irrelevant. Bessides, I just wasted a minute of my life reading the crap you posted :tongue:

PS: Peace! No insult intended!
Posted on 2004-05-31 06:41:08 by SubEvil
Thanx for that additional Info.....:)

@Sephiroth3 Thanx for your Tipp for safing much money ;-)
Posted on 2004-05-31 07:43:32 by FinalbrainXP