flat assembler
Message board for the users of flat assembler.

 Index > Main > "define" vs "equ" vs "=" Goto page 1, 2  Next
Author
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 17666
revolution
Topic was split off from here:
http://board.flatassembler.net/topic.php?t=16724

m3ntal wrote:
My understanding of define is that it's the same operation of equ - replaces text - except that it works like = inside of the assembly directives: if/while/etc.
The difference is much more subtle that that. If/else have no impact upon either define or equ, they are processed at a different stage. The manual explains the difference:
Quote:
The define directive followed by the name of constant and then the value, is the alternative way of defining symbolic constant. The only difference between define and equ is that define assigns the value as it is, it does not replace the symbolic constants with their values inside it.

Last edited by revolution on 12 May 2014, 17:47; edited 2 times in total
11 May 2014, 00:21
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Quote:
If you want to use constants for the structure offsets, then define them simply by "="

Could you elaborate on that? The advantage of defining offsets using structure definitions is obvious, but I don't see, how assembly time numeric constants are better than symbolic constants.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 13:20
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
l_inc wrote:
Could you elaborate on that? The advantage of defining offsets using structure definitions is obvious, but I don't see, how assembly time numeric constants are better than symbolic constants.

At first, you can use all assembly directives with assembly-stage constants: "used", "defined", etc.

At second, FASM process such constants much faster.

At third, FASM generates .FAS file information about assembly-stage constants, that can be useful for code completion, debugging, cross reference and other source exploring functions. For example the preprocessor symbols will not appears in the Fresh IDE code completion list, neither you can see the cross reference list. (where in the source this symbol is defined or used).
There are also, other tools that for example generate debug info from the .fas file - these will not list preprocessor symbols as well.

When such constants are small quantity and the project is small, it is not so important, but it is a bad habit, that must be corrected in time.

_________________
12 May 2014, 13:43
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Quote:
you can use all assembly directives with assembly-stage constants: "used", "defined", etc.

I don't think, used is somehow important for structure offsets. You can however use defined with symbolic constants, because it operates on expressions. A stronger argument would be the possibility to use symbolic constants with preprocessor directives such as rept .

Quote:
FASM process such constants much faster

Any proofs? Symbolic constants are processed only once, while numeric constants would potentially be processed multiple times. Besides, I've just made a little test for a single pass:
Code:
some_const = 1

x = 0
rept 1 shl 20
{
repeat 1 shl 6
x = x + some_const
end repeat
}

compiles within 7.3 seconds. Using define some_const 1 instead makes the code compile in 7.0 seconds. Thus it seems to be exactly the opposite.

Quote:
FASM generates .FAS file information about assembly-stage constants

I have no idea what information fas-files contain, but I'd find it strange if there were no information on preprocessor definitions. If that's so, then it could be an argument. A minor one however, because it's still possible to find corresponding source lines for every byte in the output.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 14:31
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
l_inc wrote:
I don't think, used is somehow important for structure offsets. You can however use defined with symbolic constants, because it operates on expressions. A stronger argument would be the possibility to use symbolic constants with preprocessor directives such as rept .

I am not talking for the "structure offsets" at all. Using other methods than struc/struct is wrong by default for the structures, because it ruins the readability of the source greatly.

And no, the preprocessor constants does not work with "defined" because the assembler knows nothing about these constants. The only case when this will work is when the preprocessor constants are equal to some numeric string. But this is a cheating actually and such use can lead to very bad, hard to detect, obscured problems. Notice where the problem appears. Now imagine you have 50k loc between the definition and the "if" statement. In different files:
Code:
define constant 1OO
if defined constant
display "Defined"
else
display "Not defined"
end if

Quote:
FASM process such constants much faster
- You are right, I was wrong. I take this argument back. But the remaining are still more important than you think.

Quote:
A minor one however, because it's still possible to find corresponding source lines for every byte in the output.

Please more details on this statement. It is not clear for me. How you can find the source line of the compiled byte? Not using .FAS file? Or?

_________________
12 May 2014, 15:01
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Quote:
And no, the preprocessor constants does not work with "defined" because the assembler knows nothing about these constants

Assembler does not need to know about symbolic constants in order to operate on expressions these constants expand into.
Quote:
But this is a cheating actually and such use can lead to very bad, hard to detect, obscured problems.

It's not cheating at all. What I normally check by defined is whether I can use/evaluate an expression in question. Is the expression something resulted from preprocessor expansion or not is completely irrelevant.

Quote:
Now imagine you have 50k loc between the definition and the "if" statement. In different files:

I have no idea, what you mean by that code. The symbolic constant constant is defined and can be used. What's the problem?

Quote:
Please more details on this statement. It is not clear for me. How you can find the source line of the compiled byte?

No idea. fasolly plugin (for ollydbg) does that, thus it seems to be pretty straightforward.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 15:15
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
l_inc wrote:
I have no idea, what you mean by that code. The symbolic constant constant is defined and can be used. What's the problem?

Did you really tried to compile this code?
Code:
flat assembler  version 1.71.20  (16384 kilobytes memory)
test_lines2.asm [3]:
if defined constant
error: invalid name.

Quote:
No idea. fasolly plugin (for ollydbg) does that, thus it seems to be pretty straightforward.

But this plugin will definitely not process the preprocessor constants, because there is no information in the .fas file about them. (Well there is information - the preprocessed text of the program, but to extract this information from there is not so easy).

Another example:
Code:
MyFunc equ obfuscate

MyFunc:
nop
.local:
nop

Another:
jmp     MyFunc.local     ; fails
jmp     obfuscate.local  ; compiles
jmp     MyFunc           ; compiles

Preprocessor symbols are special and should be used with care and only where needed.
The programmer must clearly distinct them from the assembly constants and not create situations where both can be mixed in a way that can decrease the code readability and clearness.

_________________
12 May 2014, 15:45
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Quote:
Did you really tried to compile this code?

I'm sorry, I did not compile it before. Now I did and I still don't see any kind of "obscured" problems with the code. The resulting expression cannot be evaluated and fasm correctly points to the faulting line. Now you can see the symbolic constant constant has some crap in it and you just need to find the definition, which is very easy: go to your primary source file, add something like constant fix include at the beginning and try to compile. VoilĂ  the origin of the "obscured" problem.

Even more straightforward would be to run prepsrc over the fas-file and just look for the first occurrence of the constant name.

Quote:
The programmer must clearly distinct them...

Very nice statement to teach a beginner, but it does not specify why symbolic constants are bad to be used for holding numbers.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 16:10
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 17666
revolution
The only thing I have to add is this expression:

Code:
value equ 3-1
mov eax,value * 2
mov ebx,2 * value
mov ecx,value + value
mov edx,value - value
12 May 2014, 16:14
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
revolution, great example!

l_inc wrote:
Very nice statement to teach a beginner, but it does not specify why symbolic constants are bad to be used for holding numbers.

Because for FASM they are not numbers but text.

_________________
12 May 2014, 16:23
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Quote:
Because for FASM they are not numbers but text.

Firstly, it doesn't matter what they are internally as long as you know what interface they have.

Secondly, if we consider the assembly stage, then they are even more numbers than numeric constants.

And thirdly, if we consider the preprocessing stage, then the following example shows, how only symbolic constants as numbers can save the day:

we just take the "recommended by JohnFound" way of defining structures. Then we take an awesome macro from baldr. Then we add a constant to taste and mix the substances together to a compilable condition:
Code:
include 'macro\struct.inc'

struc times [arg] {
common
match n def, arg \{
rept 1 %:1 \\{ . def  \\}
rept n-1 %:2 \\{ .\\#_\\#% def \\}
\}
}

struct IMAGE_DATA_DIRECTORY
rva dd ?
size dd ?
ends

IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16

Oops. Someone's bad taste prevents us from defining an array of structures. Now guess what happens if IMAGE_NUMBEROF_DIRECTORY_ENTRIES is defined as a symbolic constant.

revolution
Wrong usage of a feature does not prove the feature to be wrong. Symbolic constants are still subjects to a straightforward symbolic substitution and you try to ignore that fact. Not an argument at all.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 17:53
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 17666
revolution
l_inc wrote:
revolution
Wrong usage of a feature does not prove the feature to be wrong. Symbolic constants are still subjects to a straightforward symbolic substitution and you try to ignore that fact. Not an argument at all.
Actually I wasn't trying to prove anything. I just wanted to point out a common source of confusion. And you are right that it is misusing it. Of course it is easily "fixed":
Code:
value equ (3-1)
12 May 2014, 17:57
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
l_inc, the correct use of symbolic constants, does not proof the correctness of every other use of symbolic constants. I also use symbolic constants when needed - they are created to be used. But as I already said, the user must clearly distinct when the use is correct and when not.
12 May 2014, 18:07
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Wait-wait. If I understood you correctly, your suggestion was to never ever use symbolic constants to hold numbers. Meaning that if one takes an official C header and translates the numerous constants (defined in C headers with #define) to fasm, then numeric constants must be used. And that is what I expressed my doubts about.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 18:22
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
l_inc wrote:
JohnFound
Wait-wait. If I understood you correctly, your suggestion was to never ever use symbolic constants to hold numbers. Meaning that if one takes an official C header and translates the numerous constants (defined in C headers with #define) to fasm, then numeric constants must be used. And that is what I expressed my doubts about.

The use of symbolic constants (for whatever use) outside of the preprocessor should be avoided. (again - if possible, but in most cases it is possible) So, in this definition, the translation of C headers with "define" or "equ" is wrong and bad style. (BTW, many C practices are not good in assembly).
The use of symbolic constants in the preprocessor, of course is perfectly right. And how it can be different?

_________________
12 May 2014, 18:37
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Quote:
So, in this definition, the translation of C headers with "define" or "equ" is wrong and bad style

I don't think so. I'm not saying symbolic constants must be used, because I just didn't make my own decision about that, but the only valid (and unconfirmed) argument against symbolic constants for this use case till now is the lack of debugging information. However due to prepsrc debugging the preprocessor expansion is much easier than debugging the assembly stage.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 19:03
JohnFound

Joined: 16 Jun 2003
Posts: 3502
Location: Bulgaria
JohnFound
l_inc, no one can stop you to write whatever code you want...
12 May 2014, 19:16
l_inc

Joined: 23 Oct 2009
Posts: 881
l_inc
JohnFound
Well. Someone could be willing to stop me from suggesting stupid things to other people. But I see you're already tired of the discussion.

_________________
Faith is a superposition of knowledge and fallacy
12 May 2014, 19:19
fasmnewbie

Joined: 01 Mar 2011
Posts: 555
fasmnewbie
All my gurus are here. Throw in baldr and uart777, WW3 is inevitable
13 May 2014, 02:38
fasmnewbie

Joined: 01 Mar 2011
Posts: 555
fasmnewbie

Quote:
to equ or not to equ
to = or to <>
define or not to define

hehehe
13 May 2014, 02:46
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area
Goto page 1, 2  Next

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum