flat assembler
Message board for the users of flat assembler.

Index > Main > Problem with IF | if vs .if | Dilemma: to IF or NOT to IF

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
Hi people. I tried to use the if statement but the effect did not come out as expected. I am wondering if I used it correctly or there is something else that I should know. Here is the code

Code:
format PE console
include 'win32ax.inc'
include 'macro32.inc'

.code
mov dword [myData],15h
if [myData]=15h
   prtStr "Equals"
else
   prtStr "Something else"
end if

pquit

.data
myData dd ?
myData2 dd ?

.idata     


And the result is "Something else" where it should be "Equals". On the other hand, this progam below works:

Code:
format PE console
include 'win32ax.inc' 
include 'macro32.inc' 

.code 
myData=15h
;mov dword [myData],15h
if [myData]=15h 
   prtStr "Equals" 
else 
   prtStr "Something else" 
end if 

pquit 

.data 
;myData dd ?
myData2 dd ? 

.idata    


I don't see why my first program doesn't work since it is syntactically correct. I tried using the "equ" statement but the result is the same. These are the macros I used if you are interested in testing the code:

Code:
;macro32.inc
macro prtStr a{cinvoke printf, "%s", a}
macro pquit
{
        invoke system, "pause>null"
        invoke exit, 0
}

macro .idata
{
        section '.idata' import data readable
        library msvcrt, 'msvcrt.dll'
           import msvcrt,\
                  system, 'system',printf,'printf',\
                  scanf, 'scanf',gets,'gets',exit, 'exit'
}    


Thank you for your replies.
Post 11 Jul 2013, 14:56
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
fasmnewbie wrote:
On the other hand, this progam below works:
Code:
...
myData=15h 
;mov dword [myData],15h 
if [myData]=15h  
   prtStr "Equals"  
else  
   prtStr "Something else"  
end if
...    


OK. This one is interesting. Because it shouldn't compile. Moreover the comparison is also silently digested if byte, qword or dqword/xword size operator is used, but not with other size operators. I think, it's a bug.

fasmnewbie
A fasm listing is not one program: it's almost always three programs mixed together. You should clearly understand what token in a fasm listing belongs to what program:

First program: preprocessor directives (fix, define, equ, macro, include... look into the fasm manual for more). This is the first program to be executed. And it is executed at compile time and only once. It originally does nothing more, than symbolic substitution according to some tricky rules (but with later versions some calculations are also natively supported). This program creates (or expands into) the code of the second program and vanishes.

Second program: assembly control directives (if, else, repeat, times, err, display, =, eqtype... look into the fasm manual for more). This is the second program to be executed. It is executed at compile time and often multiple times until the correct execution is achieved. The results are used from the latest (correct) execution attempt only. This program creates the code of the third program and vanishes.

Third program: assembly instructions (mov, add, repne cmpsb, sysenter, vpunpckhbw... look into the fasm manual for more). This program is executed at runtime, i.e. after you compiled your program (which means, that the first two programs were executed and do not exist in the output file) and double clicked the resulting executable.

Now try to ask yourself, what the third program in your case is.
Hint: it does not contain the comparison of myData anymore.

_________________
Faith is a superposition of knowledge and fallacy
Post 11 Jul 2013, 16:01
View user's profile Send private message Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
l_inc wrote:
fasmnewbie wrote:
On the other hand, this progam below works:
Code:
...
myData=15h 
;mov dword [myData],15h 
if [myData]=15h  
   prtStr "Equals"  
else  
   prtStr "Something else"  
end if
...    


OK. This one is interesting. Because it shouldn't compile. Moreover the comparison is also silently digested if byte, qword or dqword/xword size operator is used, but not with other size operators. I think, it's a bug.

fasmnewbie
A fasm listing is not one program: it's almost always three programs mixed together. You should clearly understand what token in a fasm listing belongs to what program:

First program: preprocessor directives (fix, define, equ, macro, include... look into the fasm manual for more). This is the first program to be executed. And it is executed at compile time and only once. It originally does nothing more, than symbolic substitution according to some tricky rules (but with later versions some calculations are also natively supported). This program creates (or expands into) the code of the second program and vanishes.

Second program: assembly control directives (if, else, repeat, times, err, display, =, eqtype... look into the fasm manual for more). This is the second program to be executed. It is executed at compile time and often multiple times until the correct execution is achieved. The results are used from the latest (correct) execution attempt only. This program creates the code of the third program and vanishes.

Third program: assembly instructions (mov, add, repne cmpsb, sysenter, vpunpckhbw... look into the fasm manual for more). This program is executed at runtime, i.e. after you compiled your program (which means, that the first two programs were executed and do not exist in the output file) and double clicked the resulting executable.

Now try to ask yourself, what the third program in your case is.
Hint: it does not contain the comparison of myData anymore.


Hi inc. I believe that you are referring to the multiple-pass process, yes? From your explanations, are you suggesting that the recently uploaded value 15H (mov dword[myData], 15h) is not available to the previously compiled IF statement?

Thank you for your reply.
Post 11 Jul 2013, 17:06
View user's profile Send private message Visit poster's website Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
ok guys. I think I need to rephrase my question

What did I do wrong in using the IF directive in the first program regardless of the second program's output? Is it even the correct way to use the IF statement? tqvm.
Post 11 Jul 2013, 17:29
View user's profile Send private message Visit poster's website Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
"if", "then", "else", "end if" are not run time statements, but assembler directives. So, this directives work only during compilation and this way can't check whether or not your variable contains 15h

Use assembly instructions instead:

Code:
format PE console 
include 'win32ax.inc' 
include 'macro32.inc' 

.code 
        mov   dword [myData], 15h
        cmp   dword [myData], 15h    ; compare
        je    .equal                 ; jump if equal

        prtStr "Something else"      ; else, not equal
        jmp  .to_the_end             ; jump to the end

.equal:
        prtStr "Equals" 

.to_the_end:

        pquit 

.data 
myData dd ? 
myData2 dd ? 

.idata     
Post 11 Jul 2013, 17:54
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1419
Location: Toronto, Canada
AsmGuru62
I believe if is a conditional assembly directive.
It means that the code will be assembled differently based on some condition.

I believe at run-time you should use .if -- notice the dot in front.
I never use these directives, but you should look into IF.INC file in FASM package.
This file has the run-time directives like, WHILE, IF/ELSE, etc.
Post 11 Jul 2013, 17:55
View user's profile Send private message Send e-mail Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
JohnFound wrote:
"if", "then", "else", "end if" are not run time statements, but assembler directives. So, this directives work only during compilation and this way can't check whether or not your variable contains 15h

Use assembly instructions instead:

Code:
format PE console 
include 'win32ax.inc' 
include 'macro32.inc' 

.code 
        mov   dword [myData], 15h
        cmp   dword [myData], 15h    ; compare
        je    .equal                 ; jump if equal

        prtStr "Something else"      ; else, not equal
        jmp  .to_the_end             ; jump to the end

.equal:
        prtStr "Equals" 

.to_the_end:

        pquit 

.data 
myData dd ? 
myData2 dd ? 

.idata     


That's what I thought. TQVM John. For the time being, maybe I'll just skip those high-level constructs.
Post 11 Jul 2013, 18:06
View user's profile Send private message Visit poster's website Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
AsmGuru62 wrote:
I believe if is a conditional assembly directive.
It means that the code will be assembled differently based on some condition.

I believe at run-time you should use .if -- notice the dot in front.
I never use these directives, but you should look into IF.INC file in FASM package.
This file has the run-time directives like, WHILE, IF/ELSE, etc.


Thank you for the explanation.
Post 11 Jul 2013, 18:09
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
AsmGuru62 wrote:
I never use these directives, but you should look into IF.INC file in FASM package.
This file has the run-time directives like, WHILE, IF/ELSE, etc.

There's not such term as "run-time directives". .if, .while, .repeat etc. are macros, not directives. Those are expanded into assembly instructions.

_________________
Faith is a superposition of knowledge and fallacy
Post 11 Jul 2013, 18:18
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1419
Location: Toronto, Canada
AsmGuru62
Ok. Thanks.
Post 11 Jul 2013, 19:15
View user's profile Send private message Send e-mail Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
AsmGuru62
Don't thank me. That comment wasn't for you. Smile I'm sure, you know what those macros are about.

_________________
Faith is a superposition of knowledge and fallacy
Post 11 Jul 2013, 19:26
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1419
Location: Toronto, Canada
AsmGuru62
I never use these, so I am really not aware.
My macro skills are simplest replacement of parameters -- i.e. very poor.
Post 11 Jul 2013, 20:16
View user's profile Send private message Send e-mail Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7797
Location: Kraków, Poland
Tomasz Grysztar
l_inc wrote:
OK. This one is interesting. Because it shouldn't compile. Moreover the comparison is also silently digested if byte, qword or dqword/xword size operator is used, but not with other size operators. I think, it's a bug.
It is a funny bug. I fixed it already, but i wait with release till I decide whether to ship some more fixes with it as well.
Post 11 Jul 2013, 20:44
View user's profile Send private message Visit poster's website Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777
fasmnewbie wrote:
Quote:
maybe I'll just skip those high-level constructs
It is your choice whether or not to use .if, not John's, and you can use the .if predefined by FASM in \INCLUDE\MACRO\IF.INC, or edit/extend it or write your own. .if is just a shortcut to cmp-jxx and invoke is a shortcut to push-call. Macros like proc, invoke, stdcall, struct are also high-level constructs, macros, fake/pseudo instructions, not "real ASM" by the CPU manufacturer's definition.

Often times, we hear programmers say "That's not real ASM!", and in most cases, they are speaking from the perspective of a X86-only programmer who has an exclusive narrow-minded definition of what ASM is and who refuses to advance with technology. Today, ARM is the most widely used CPU in the world, not X86. Once you evolve into a multi-CPU programmer, it's hard to say what "real ASM" is. Examples: In ARM CPU, mov r, 12345678h is not real ASM; it may be encoded as a series of binary orr+lsl's or movw/movt. In MIPS, mov x, y is not real ASM; it may be encoded as addi x, y, 0.

IMO, the best .if would recognize HL variables with known types and sizes (strict: i8/u8/i16/u32/etc, no vague "w/ord/h/alf"s), select un/signed operations without having to use separate symbols or "signed" prefix, support calls and be compatible with major CPUs: Intel+ARM. Why go 1/2 way with it?
Post 11 Jul 2013, 23:04
View user's profile Send private message Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
uart777 wrote:
fasmnewbie wrote:
Quote:
maybe I'll just skip those high-level constructs
It is your choice whether or not to use .if, not John's, and you can use the .if predefined by FASM in \INCLUDE\MACRO\IF.INC, or edit/extend it or write your own. .if is just a shortcut to cmp-jxx and invoke is a shortcut to push-call. Macros like proc, invoke, stdcall, struct are also high-level constructs, macros, fake/pseudo instructions, not "real ASM" by the CPU manufacturer's definition.

Often times, we hear programmers say "That's not real ASM!", and in most cases, they are speaking from the perspective of a X86-only programmer who has an exclusive narrow-minded definition of what ASM is and who refuses to advance with technology. Today, ARM is the most widely used CPU in the world, not X86. Once you evolve into a multi-CPU programmer, it's hard to say what "real ASM" is. Examples: In ARM CPU, mov r, 12345678h is not real ASM; it may be encoded as a series of binary orr+lsl's or movw/movt. In MIPS, mov x, y is not real ASM; it may be encoded as addi x, y, 0.

IMO, the best .if would recognize HL variables with known types and sizes (strict: i8/u8/i16/u32/etc, no vague "w/ord/h/alf"s), select un/signed operations without having to use separate symbols or "signed" prefix, support calls and be compatible with major CPUs: Intel+ARM. Why go 1/2 way with it?


Hi uart, thanks for the comment and advice. I didn't mean to skip HL construct features of FASM. Just want to avoid anything confusing until I get it right.

I did use the .if directive but it then led me to another confusion in another program. e.g

Code:
format PE console
include 'win32ax.inc'
include 'macro32.inc'
entry main

.code
main:
prtStr "Enter an integer: "
getInt number
xor eax, eax
mov eax, [number]

.if dword [number] < 0 ;doesn't work
    prtStr "NEGATIVE"
.else
    prtStr "+"
.endif
pquit
.data
number dd ?

.idata    


I don't know whats wrong but the logical comparison didn't work. It is supposed to print the string "NEGATIVE" if [number] is negative (< 0). I suspect this has something to do with C's unsigned/signed issue? I don't know. Maybe you can shed a light for me on this one. Here is the macro if you're interested in testing the code.

Code:
;macro32.inc
macro getInt a{cinvoke scanf, "%d", a}
macro prtStr a{cinvoke printf, "%s", a}
macro pquit
{
        invoke system, "pause>null"
        invoke exit, 0
}
macro .idata
{
        section '.idata' import data readable
        library msvcrt, 'msvcrt.dll'
           import msvcrt,\
                  system, 'system',printf,'printf',\
                  scanf, 'scanf',gets,'gets',exit, 'exit'
}    


Thanks for the comments guys.
Post 16 Jul 2013, 09:05
View user's profile Send private message Visit poster's website Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
Tomasz Grysztar wrote:
l_inc wrote:
OK. This one is interesting. Because it shouldn't compile. Moreover the comparison is also silently digested if byte, qword or dqword/xword size operator is used, but not with other size operators. I think, it's a bug.
It is a funny bug. I fixed it already, but i wait with release till I decide whether to ship some more fixes with it as well.


Thanks for stopping by Thomas.
Post 16 Jul 2013, 09:11
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
fasmnewbie
Quote:
Hi uart, thanks for the comment and advice.

If you're interested in more opinions, then mine is the opposite one. I don't find any of the uart777's arguments to be valid and would strongly discourage you from using macros from extended headers at the beginning. Your current problem is one reason to stop using those. But as soon as you'll be feeling like a guru in assembly and at least one of the higher level languages (I'd suggest C), you'll be able to expertly decide yourself.

Quote:
I suspect this has something to do with C's unsigned/signed issue?

That's almost correct. It has nothing to do with C though. Let us take a look at the documentation:
3.2.2 Structuring the source wrote:
The values are compared as unsigned ones, unless the comparison expression is preceded by the word signed.

Thus your condition
Code:
.if dword [number] < 0    
is always false, because unsigned numbers cannot be less than zero. What you need is
Code:
.if signed [number] < 0    
to make the .if macro generate signed comparison.

_________________
Faith is a superposition of knowledge and fallacy
Post 16 Jul 2013, 09:48
View user's profile Send private message Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
l_inc wrote:
fasmnewbie
Quote:
Hi uart, thanks for the comment and advice.

If you're interested in more opinions, then mine is the opposite one. I don't find any of the uart777's arguments to be valid and would strongly discourage you from using macros from extended headers at the beginning. Your current problem is one reason to stop using those. But as soon as you'll be feeling like a guru in assembly and at least one of the higher level languages (I'd suggest C), you'll be able to expertly decide yourself.

Quote:
I suspect this has something to do with C's unsigned/signed issue?

That's almost correct. It has nothing to do with C though. Let us take a look at the documentation:
3.2.2 Structuring the source wrote:
The values are compared as unsigned ones, unless the comparison expression is preceded by the word signed.

Thus your condition
Code:
.if dword [number] < 0    
is always false, because unsigned numbers cannot be less than zero. What you need is
Code:
.if signed [number] < 0    
to make the .if macro generate signed comparison.


TQVM i_inc. The comparison works like a charm now. I have to agree with you on some point about using the HL constructs at the beginning of the learning curve. Bearing HLL mindset while doing ASM is not helpful at all.




[/b]
Post 16 Jul 2013, 10:20
View user's profile Send private message Visit poster's website Reply with quote
fasmnewbie



Joined: 01 Mar 2011
Posts: 555
fasmnewbie
AsmGuru62 wrote:
I never use these, so I am really not aware.
My macro skills are simplest replacement of parameters -- i.e. very poor.


LOL. You should see my macros before you rank yourself "very poor" Laughing
Post 16 Jul 2013, 10:44
View user's profile Send private message Visit poster's website Reply with quote
uart777



Joined: 17 Jan 2012
Posts: 369
uart777
fasmnewbie:
Quote:
I have to agree with you on some point about using the HL constructs at the beginning of the learning curve
I agree, it's your choice. When I was learning ASM (about 17-19 years ago), I never used .if because I thought it was important to learn "real ASM" first. I was a beginner, not experienced in macros and did not know what code is produced by MASM's .if/.while.

Now, I use my own .if to increase production, especially in my main source files for calling and general program flow. Iczelion was a famous ASM programmer who used .if/.while/etc very clean and professionally in 30+ WinASM examples: http://win32assembly.programminghorizon.com/tutorials.html

I_inc wrote:
Quote:
If you're interested in more opinions, then mine is the opposite one
My opinion is that we should be allowed to write code however we want. It is John with his communist mentality who tries to take away their freedom and impose a style on them that can't be logically defended.

Quote:
I'd suggest C
So, you recommend using a C compiler instead of FASM (as if all C compilers are the same). Why would you assume that any random assembler (for C compiler) is better than FASM? Why should we not use FASM as the assembler/linker/backend? Which assembler is best for this purpose?

Quote:
I don't find any of the uart777's arguments to be valid
Advantages of .if versus cmp-jxx

* .if can be portable, compatible with any CPU: X86, ARM, MIPS, JVM, etc. On ARM - most widely used CPU in the world - cmp v1, 12345678h and cmp v1, [m] are not real ASM instructions, you'd have to create HL macros to support them.
* cmp-jxx requires the programmer to manually create labels whereas .if automatically generates unique labels.
* .if is easy to translate to/from other languages, algorithms and pseudo code.
* .if does not require the programmer to stop and think to invert the condition. Example: "if less" = "if not greater or equal".
* .if condition is written on the same line.
* .if can be edited and/or extended to support calls.
* .if is designed for high-volume production and making real-life applications.
* .if is pure English. "cmp" is not a real word

Here are some arguments that I would love for you to disprove. I challenge anyone to improve my design for a HL compiler: http://board.flatassembler.net/topic.php?t=15588
Post 17 Jul 2013, 00:57
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.