problem:
.if eax!=0
call func1
.if eax!= exit to main if block
call func2
.if eax!= exit to main if block
call func3
.if eax!= exit to main if block
.endif
.break .if eax!=0 only in cycle work...
every .if needs a matching .endif
Hi korte,
A typical usage of .BREAK :
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
That's the problem. :bdg
I do not like a lot ".if - .endif".
Solution is something like the while loop of the ". Break. If" combination
Vortex: OK
I know this.
But I do not want to cycle.
maybe a back testing, once running cycle.
Vortex: OK
I know this.
But I do not want to cycle.
maybe a back testing, once running cycle.
include \masm32\include\masm32rt.inc
.code
AppName db "Masm32:", 0
start:
.Repeat
.if eax!=1234h
call MyTest
.Break .if eax==IDNO
call MyTest
.Break .if eax==IDNO
call MyTest
.Break .if eax==IDNO
.endif
.Until 1
exit
MyTest proc
MsgBox 0, "Hello World", addr AppName, MB_YESNO
ret
MyTest endp
end start
Note that the .Repeat loop does not produce any code:
00401009 |. 3D 34120000 cmp eax, 1234
0040100E |. 74 1E je short 0040102E
00401010 |. E8 20000000 call 00401035
00401015 |. 83F8 07 cmp eax, 7
00401018 |. 74 14 je short 0040102E
0040101A |. E8 16000000 call 00401035
0040101F |. 83F8 07 cmp eax, 7
00401022 |. 74 0A je short 0040102E
00401024 |. E8 0C000000 call 00401035
00401029 |. 83F8 07 cmp eax, 7
0040102C |. 74 00 je short 0040102E
0040102E |> 6A 00 push 0 ; /ExitCode = 0
00401030 \. E8 1B000000 call <jmp.&kernel32.ExitProcess> ; \ExitProcess
korte,
Just get used to the .IF notation and how its nested, it is close enough to how the processor works and you get efficient code from it for all but the most critical algorithm design. There is a trick to using it to be both fast and reliable,
Always write your .IF .ENDIF as pairs and work inbetween then.
.if condition
.endif
This way as long as you keep an eye on some formatting like accurate indenting you always know where you are in the .IF block.
The solution I posted above is absolutely efficient for what korte is trying to do. The more tests you have to perform, the uglier it gets with nested if's. The Repeat/break construct produces the same code and is clearer imho.
.if eax!=1234h
call MyTest
.if eax!=IDNO
call MyTest
.if eax!=IDNO
call MyTest
.if eax!=IDNO
call MyTest
.if eax!=IDNO
call MyTest
.endifs
.endif
.endif
.endif
.endif
.Repeat
.if eax!=1234h
call MyTest
.Break .if eax==IDNO
call MyTest
.Break .if eax==IDNO
call MyTest
.Break .if eax==IDNO
call MyTest
.Break .if eax==IDNO
call MyTest
.Break .if eax==IDNO
.endif
.Until 1
Don't indent by 8 and you won't have the problem. Apart from a lookup table for the range passed to a block of testing information, the .IF notation is clean and efficient.
cmp eax,1234h
jz Break0
push 3
pop ecx
Loop00: push ecx
call MyTest
pop ecx
cmp eax,IDNO
jz Break0
dec ecx
jnz Loop00
Break0:
:P
Dave,
Write a WndProc with it, especially a big one. The only thing I have seen that actually works better is a lookup table of message values but it takes a bit more setting up.
For a WndProc, I prefer Switch. But korte's case is a bit different in that he passes a number of sequential tests. What about this:
SeqTest IDNO, MyTest, "Click Yes to continue", "A test", MB_YESNO
SeqTest IDCANCEL, MyTest, "Click OK", "Another test", MB_OKCANCEL
SeqTest IDYES, MyTest, "Don't click Yes", "And the last one", MB_YESNOCANCEL
MsgBox 0, "Congrats, you passed the first series!", "Hi", MB_OK
SeqEnd
Testbed attached :wink