News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

The difference between .IF and IF

Started by StillLearningMasm, May 15, 2019, 03:32:52 AM

Previous topic - Next topic

StillLearningMasm

I am trying to use .IF to detect a code label. I can currently do it using IF but the way I expected it to work does not work for .IF.  Here is my existing IF statement:

if .type main eq 1
Inc eax
else
dec eax
endif


I tried using the same logic for the .IF statement be get this error:  immediate operand not allowed
This is the code I used for the .IF statement:


.if .type main == 1
Inc eax
.else
dec eax
.endif


What am I doing wrong? Does the .IF work the same way? Can .IF be used to detect bit values? If so how do you do it?



daydreamer

Quote from: StillLearningMasm on May 15, 2019, 03:32:52 AM
I am trying to use .IF to detect a code label. I can currently do it using IF but the way I expected it to work does not work for .IF.  Here is my existing IF statement:

if .type main eq 1
Inc eax
else
dec eax
endif


I tried using the same logic for the .IF statement be get this error:  immediate operand not allowed
This is the code I used for the .IF statement:


.if .type main == 1
Inc eax
.else
dec eax
.endif


What am I doing wrong? Does the .IF work the same way? Can .IF be used to detect bit values? If so how do you do it?
in qeditor check help files on masm
.IF .ELSE .ENDIF ,notice its a dot before it,is for code
IF ELSE without dot is used for macros and conditional assembly

you use TEST to test bit values,it perform AND without results,only setting flags,same as CMP is a SUB without results,just setting flags
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

StillLearningMasm

I understand the difference between the .IF statement and the IF statement. What I am trying to understand is when to use "EQ" and  "==" when comparing bit values in a .IF statement and a IF statement.
There does not seem to be any "rules" to determine when to use them.

hutch--

You use the .IF block statements for runtime code, the IF block statements are for conditional assembly. The EQ and == operators are evaluation comparisons for the pre-processor, IE : Macros.

StillLearningMasm

I am still confused. In my example I used the following IF statement

if .type main eq 1

I have since learned that to do the same test for using the .IF statement I should use the following:

.if .type main eq 1

What I am confused about is the masm reference says that "EQ" for the .IF statement is replaced by using "==". I tried that and it does not work. So what is the "rule" to know when to use "==" instead of "EQ" when using the .IF statement?

hutch--


TYPE


Syntax: TYPE expression


Description

The TYPE operator returns a value and size and distance attributes appropriate to <expression>. You can use the constant returned by TYPE directly or use the attributes returned by TYPE. For example, you can use the returned attribute to specify a type for PTR.

<expression> Returns

Variable Number of bytes allocated for each element
Structure Total number of bytes in the structure
Constant 0
Code label Distance
Register Size of register in bytes

StillLearningMasm

I understand what and when to use TYPE.

What I am confused about is the masm reference says that "EQ" for the .IF statement is replaced by using "==". I tried that and it does not work. So what is the "rule" to know when to use "==" instead of "EQ" when using the .IF statement?

How does a person know when to use "==" instead of "EQ" when using a .IF statement. They are not interchangeable  and there seems to be some "rule" to know when to use each. What is that rule?

jj2007

Below is a little testbed. You absolutely need to understand the difference between assembly and runtime.

These IFs are assembly time - only one branch will generate code:
IF someitem EQ 123
  echo yeah, it's 123
  mov eax, 123
else
  echo no, it's not 123
  mov eax, someitem
endif


The .IFs are runtime - both branches will generate code:
.IF someitem == 123
  print "yeah, it's 123"
  mov eax, 123
.else
  print "no, it's not 123"
  mov eax, someitem
.endif


Use the tmp$ stuff below to understand assembly time problems
Use
pushad
print str$(whatever), " is the value", 13, 10
popad

to understand runtime problems.

Btw .type is an obsolete version of opattr.

include \masm32\include\masm32rt.inc

.code
start:
oa = opattr(start)
tmp$ CATSTR <opattr=>, %oa
% echo tmp$

if .type start eq 1 ; UAsm throws Error A2189: Operand must be relocatable
echo dot type is one
else
tmp$ CATSTR <dot type=>, %(.type start)
% echo tmp$
endif
if type start eq 1
echo type is one
else
tmp$ CATSTR <type=>, %(type start)
% echo tmp$
endif
; .err
  inkey "hit any key" ; a Masm32 macro
  exit

end start

StillLearningMasm

I guess I am still having a problem trying to explain my original question.

I understand the difference between the .IF statement and the IF statement.
I also understand the .TYPE statement and the TYPE statement.

If I am using a .IF statement I would like to know when to use "==" instead of using "EQ" in the .IF statement.
According to the masm documentation I have it says to use "==" in a ".IF" statement and to use a "EQ" in a "IF" statement. But I found this not to be true.
For example the instruction below is using "IF" with "EQ":

if .type main eq 1

The code below is using ".IF" with "EQ". NOT the "==" as the masm documentation says it is suppose to.

.if .type main eq 1

Notice that both instruction are using "EQ". The first one is using "EQ" as is expected for a "IF" instruction but the second one is using "EQ" for a ".IF" instruction.
The second one is not using "==" as my masm documentation states it should. If I do this:

.if .type main == 1

I get this error: immediate operand not allowed.

So how do I know when to use "==" instead of "EQ" for the ".IF" instruction?

jj2007

Quote from: StillLearningMasm on May 15, 2019, 08:49:17 AM
According to the masm documentation I have it says to use "==" in a ".IF" statement and to use a "EQ" in a "IF" statement.

The docs are correct.

Your .if .type main eq 1 is actually equivalent to .if 0

Why that? Try assembling these lines in code that contains a main label:

tmp$ CATSTR <TheArg=>, %(.type main eq 1)
% echo tmp$
tmp$ CATSTR <TheArg=>, %((.type main) eq 37)      ; 37 is type label
% echo tmp$
.err

The output window will show
TheArg=0
TheArg=4294967295


The first expression is FALSE, because the .type of a label is not 1. This is an assembly time expression.
The second one is true. Yes, main is a label, and its .type is 37 (same for opattr).
Assembly time TRUE is -1, and echo will display that number as 2^32-1 = 4294967295

Hope it helps ;-)

StillLearningMasm

I STIIL have not got a answer to my question:

How do I know when to use "==" instead of "EQ" for a ".IF" instruction?

The .IF instruction below  is the way it is suppose to be. This does NOT match the masm documentation:

.if .type main eq 1

The .IF instruction below is the way it says it should be according to masm documentation:

.if .type main == 1

Notice that one has "==" the other has "EQ".

WHEN is it correct to use "==" in a .IF  instruction?
WHEN is it correct to use "EQ" in a .IF instruction?


sinsi


jj2007

Sinsi is right, the docs are right. The problem with .if .type main eq 1 is that you must write it as .if (.type main eq 1) to understand what it does. The expression .type main eq 1 gets evaluated at assembly time and results to zero. Which means that
.if .type main eq 1
is exactly the same as
.if 0 ; (and you could write that as .if FALSE, too)

Now unfortunately .if 0 and .if 1 are not explicitly documented. What they do is as follows:
int 3 ; let the debugger stop here
.if 0
  mov eax, 111h
  mov ebx, 222h
  mov ecx, 333h
.endif
mov eax, eax ; we just insert a meaningless instruction to understand where we are in the disassembly
.if 1
  mov edx, 444h
  mov esi, 555h
  mov edi, 666h
.endif
  nop
  nop


Now watch what the .if 0 does - it inserts a jmp 4010B6, which is actually the mov eax, eax:

CPU Disasm
Address       Hex dump                        Command                                  Comments
004010A4      ³.  CC                          int3
004010A5      À. EB 0F                       jmp short 004010B6
004010A7      Ú.  B8 11010000                 mov eax, 111
004010AC      ³.  BB 22020000                 mov ebx, 222
004010B1      ³.  B9 33030000                 mov ecx, 333
004010B6      ³>  8BC0                        mov eax, eax                             ; the meaningless 'delimiter'
C0003         ³.  BA 44040000                 mov edx, 444
004010BD      ³.  BE 55050000                 mov esi, 555
004010C2      ³.  BF 66060000                 mov edi, 666
004010C7      ³.  90                          nop
004010C8      ³.  90                          nop


In short, .if 0 protects its branch against execution, but the code inside will still be generated. Note also that .if 1 does ... nothing, absolutely nothing. It just gets completely ignored by the assembler.

BugCatcher

Compiler directives tell the assembler how to compile your code."EQU". They disappear after the program is compiled.
Run time directives "==" .if eax==1 is part of the running code.

hutch--

Maybe you should tell us what MASM documentation you are using. It sounds like you are trying to use very old MS-DOS documentation, much of which does not apply to Win32 assembler.