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?
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
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.
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.
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?
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
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?
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
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?
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 0Why 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 ;-)
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?
Use == with .IF
Use EQ with IF
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.
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.
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.
This reminds me this story: :lol:
https://www.zinzin.com/observations/2014/describing-the-color-white-to-a-blind-person/