Question
I'm trying to make a loop in masm32 running under Windows Vista, however I did it this way and even though it actually finishes the loop, it crashes and I see no obvious reason why...any ideas?
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
.data
ProgramText db "Looping!", 0
.data?
loop_stopper dd ?
.code
start:
mov loop_stopper,2
loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper
jg loop_start
end start
Edit
Did
invoke StdOut, offset ProgramText
still crashes...
Solution
You need to have an "exit" to end your application. Also, my personal style is to put everything inside a subroutine, but that's just me.
something like:
.code
start:
call main
inkey
exit
main proc
mov loop_stopper,2
loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper
jg loop_start
ret
main endp
end start
OTHER TIPS
Seems to me the order of your instructions is wrong. You do a comparison, then a decrement, then a conditional jump. Your flag values from the comparison might possibly be altered by the decrement.
loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper
jg loop_start
ret
When I was doing assembly programming, I did it this way: decrement the counter, then loop if non-zero.
loop_start:
invoke StdOut, addr ProgramText
dec loop_stopper
jnz loop_start
ret
Of course, depending on the processor, you might put the loop-variable in a register which allows you to decrement and loop using a single instruction. ( e.g the Z80 'djnz' instruction. I can't remember back that far which register it actually was, though the 'B' register seems to ring a bell).
Also, as some others have suggested, you don't appear to be cleaning up your memory space. Most programs are actually 'CALLS' to your code. Therefore you need to preserve code and stack pointers so that you do a graceful "RETURN" to the calling part of the operating system. If you haven't done that, your 'RETURN' can take you to wherever the top of the stack happens to be pointing, usually with disastrous consequences.
ClubPetey is right. MASM doesn't produce an epiloge for your code. So the processor continues execution of what it finds behind the last written instruction. exit explicitly asks the operating system to stop executing the program.