News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Conditional IFs (Solved)

Started by Shooter, December 08, 2010, 01:56:48 AM

Previous topic - Next topic

Shooter

I copied and am trying to convert the following from a MASM32 example, TABDEMO, to GoASM but I'm getting an error (below):

DlgProc FRAME hwnd,uMsg,wParam,lParam
   LOCAL ts:TC_ITEM              ;In Commctrl.h
   MOV EAX,[uMsg]
   AND   EAX,0FFFFh
   SHR   EDX,16                      ;Should this be EDX, or should it be EAX? How did EDX get loaded??
      #IF EDX==BN_CLICKED
         #IF EAX==IDCANCEL
         INVOKE SendMessage,[hwnd],WM_CLOSE,0,0
         #ELSE EAX==IDOK
         INVOKE SendMessage,[hwnd],WM_CLOSE,0,0
         #ENDIF
      #ENDIF
     .
     .
     .

Error:
Could not evaluate expression in conditional directive:-
EDX

Am I doing something wrong, or am I going to have to convert each occurrence of these conditional IFs to something like this:

DlgProc FRAME hwnd,uMsg,wParam,lParam
   LOCAL ts:TCITEM               ;In Commctrl.h
   MOV EAX,[uMsg]
   AND   EAX,0FFFFh
   SHR   EDX,16                      ;Should this be EDX, or should it be EAX? How did EDX get loaded??
   CMP EDX, BN_CLICKED
   JNE >.BN_NOT_CLICKED
      CMP EAX,IDCANCEL
      JNE >.CHK_IDOK
      INVOKE SendMessage,[hwnd],WM_CLOSE,0,0
      JMP >.BN_CLICK_CHECK
   .CHK_IDOK
      CMP EAX,IDOK
      JNE >.BN_NOT_CLICKED
      INVOKE SendMessage,[hwnd],WM_CLOSE,0,0
   .BN_NOT_CLICKED
     .
     .
     .


Many thanks to the Guru's of this forum,
-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

donkey

#1
Hi Shooter,

GoAsm has no runtime conditionals, the #IF directive is for conditional compilation and cannot be used to test a condition at run time.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Shooter

Quote from: donkey on December 08, 2010, 07:18:07 AM
GoAsm has no runtime conditionals, the #IF directive is for conditional compilation and cannot be used to test a condition at run time.
Edgar,
Thanks for the answer. I take it my example is the way I'm going to have to do it?

I read in a post that Jeremy was not going to include any form of IFs due to the confusion it would cause (but something similar might be considered). I, however, am one of those that are confused by the differences between 'compilation' and 'run time'. Would you help me to understand how one can work in 'compilation' vs. 'run time'? The way I understood it, 'run time' is the only time a program can work. Please excuse my naivete.

Thanks,
-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

jj2007

Both examples in Masm syntax.
Assembly time:
MyFlag = 1
IF MyFlag
  push eax
ELSE
  push ecx
ENDIF

It's also called "conditional assembly" and will generate only one of the push instructions.

Run time:
mov MyFlag, 1
.IF MyFlag
  push eax
.ELSE
  push ecx
.ENDIF

Here, MyFlag is a variable located in memory. Its value is being checked, and one of the push instructions will be executed. Both are present in the code, though.
To see the difference, you should use OllyDbg.

Tight_Coder_Ex

Think of it in this context

#IF either includes or excludes code and is only relevant at compile time.

.IF on the other hand is still only relevant at compile time, but the code it generates is evaluated while app is running, hence "runtime".  I like using this conditional as I don't have to invent or be bothered with unnecessary local labels as in the example below.

00000000   2   AD       lodsd
00000001   1   8B D8       mov ebx, eax
00000003   2   AD       lodsd
     
00000004   1   8B C8       mov ecx, eax


00000006   2   AD       @@: lodsd
00000007   1   8B D0       mov edx, eax
00000009   2   AD       lodsd
     
      .if edx == [esp + 8]
0000000A   2   3B 54 24 08 * cmp edx, [esp + 008h]
0000000E   1   75 0A * jne @C0001
00000010   1   8D 74 24 04       lea esi, [esp + 4]
00000014   2   FF D0       call eax
00000016   1   73 16       jnc @F
      .else
00000018   1   EB 02 * jmp @C0003
0000001A *@C0001:
0000001A  7,8  E0 EA       loopnz @B
      .endif
0000001C *@C0003:
     
      .if !ebx
0000001C   1   0B DB * or ebx, ebx
0000001E   1   75 05 * jne @C0004
00000020   1   E9 00000000 E       jmp DefWindowProc
      .endif
00000025 *@C0004:
     
00000025   3   87 1C 24       xchg [esp], ebx
00000028   1   53       push ebx
00000029   1   E9 00000000 E       jmp CallWindowProc
     
0000002E   1   33 C0       @@: xor eax, eax
00000030   2   C2 0010       ret 16



donkey

Quote from: Shooter on December 08, 2010, 12:02:27 PM
Quote from: donkey on December 08, 2010, 07:18:07 AM
GoAsm has no runtime conditionals, the #IF directive is for conditional compilation and cannot be used to test a condition at run time.
Edgar,
Thanks for the answer. I take it my example is the way I'm going to have to do it?

I read in a post that Jeremy was not going to include any form of IFs due to the confusion it would cause (but something similar might be considered). I, however, am one of those that are confused by the differences between 'compilation' and 'run time'. Would you help me to understand how one can work in 'compilation' vs. 'run time'? The way I understood it, 'run time' is the only time a program can work. Please excuse my naivete.

Thanks,
-Shooter

Hi Shooter,

Yes, you have to manually code all condition blocks and loops, there is no equivalent to the MASM .IF high level construct in GoAsm. Though it has been on Jeremy's to-do list for some time and will eventually be added for now you have to code them the way you have shown.

Compile time and run time are fairly easy to understand. Compile time is the process of code generation, it can only use values that are known and usually affect whether a block of code is included or the constants used. For example if you look at the header files there are many compile time switches, the most prevalent are WINVER, WIN64 and UNICODE, which swap out values and definitions based on what OS version, address size and character set you want your application to support. Run time conditionals make a comparison based on values that are unknown at the time you build your program, for example the value of EDX or [uMsg], the program's execution path is altered by the values but no new code is generated.

By the way your code above does have a problem, it is a WM_COMMAND handler though it does not seem to check for the message, EDX should have been loaded with wParam. You were right to ask ";Should this be EDX, or should it be EAX? How did EDX get loaded??". I'm going to leave it to you to do the correction.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

donkey

Shooter,

I split and moved your RadAsm debugger issue as it is not really GoAsm related and belongs more in the RadAsm support forum. You can find the topic here:

Setting up debugger
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Shooter

Quote from: donkey on December 09, 2010, 02:19:03 AM
I split and moved your RadAsm debugger issue as it is not really GoAsm related and belongs more in the RadAsm support forum. You can find the topic here:

Setting up debugger

Edgar,
I didn't even know that was possible, but it makes sense. Thanks.

Btw, your explanation about the differences between the 'ifs' was rather in depth... I'm gonna have to let it soak in some more and 'brew' before I completely understand it.  :red

-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.