flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Inconsistent labels?

Author
Thread Post new topic Reply to topic
Rahsennor



Joined: 07 Jul 2007
Posts: 61
Rahsennor
This may or may not be a bug in fasm. If it isn't, feel free to ignore me. Very Happy

This code:
Code:
x equ edi+1

if x eqtype edi
 display 'register',13,10
end if

if x eqtype 1
 display 'number',13,10
end if

if x eqtype edi+1
 display 'both',13,10
end if    
Does this:
Code:
flat assembler  version 1.68  (16384 kilobytes memory)
both
1 passes, 0 bytes.    
But this code:
Code:
label x at edi+1

if x eqtype edi
 display 'register',13,10
end if

if x eqtype 1
 display 'number',13,10
end if

if x eqtype edi+1
 display 'both',13,10
end if    
Does this:
Code:
flat assembler  version 1.68  (16384 kilobytes memory)
number
1 passes, 0 bytes.    
Confused
If you don't get what I mean, try this:
Code:
if x eqtype 1
 display 'number',13,10
 db x
end if

if x eqtype edi+1
 display 'both',13,10
 db x-edi
end if    
If x is a label, it picks the first statement and whinges about the resulting "db edi+1". If x is an equate:
Code:
flat assembler  version 1.68  (16384 kilobytes memory)
both
temp.asm [10]:
 db x-edi
error: invalid argument.    
Which is the same result as for "db edi+1-edi"; no register algebra. However, the same db with x as a label does work: x-edi = 1, assembly succeeds.

I see two things: first, eqtype behaves differently depending on whether its arguments are labels; and second, db permits or forbids register algebra depending on whether or not its argument contains a label. Are these behaviours intentional or not? Question
Post 04 Dec 2010, 02:02
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3500
Location: Bulgaria
JohnFound
in your first example, "equ" works in preprocessing stage and the assembler never can see the "label" X (it is not label but symbolic constant) it can see only the string "edi+1" replaced in the text of the source.
On the other hand, all labels are numbers once defined, so in your second example the assembler will see the label X, not the text "edi+1".
Post 04 Dec 2010, 07:16
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Rahsennor



Joined: 07 Jul 2007
Posts: 61
Rahsennor
Rolling Eyes The preprocessor is not involved. I used equ simply to illustrate. Substitute like so:
Code:
label x at edi+1

if x eqtype edi+1 ; fails!
 display 'with label',13,10
end if

if edi+1 eqtype edi+1 ; same address, but now it works
 display 'without label',13,10
end if    
And the same for this:
Code:
label x at edi+1

db x-edi ; works
db edi+1-edi ; same value: fails    
The problem is that the address is the same, but the result is different. This does not, to me, make any sense. Can anyone enlighten me? Confused

EDIT: To elaborate, say I want to make a macro that takes an address as an argument. That macro must decide if it can save the address directly with dd or if it must use an alternative encoding. How do I do it?
Post 04 Dec 2010, 10:10
View user's profile Send private message Reply with quote
Tomasz Grysztar
Assembly Artist


Joined: 16 Jun 2003
Posts: 7724
Location: Kraków, Poland
Tomasz Grysztar
This is related to how parser sees the source. Unless in a special context (after the AT operator, or inside the square brackets), "edi+1" is seen as two separate expressions. "edi" - register, and "+1" - a numerical expression. That's why this works:
Code:
if eax 4 eqtype edi+1
 display 'register and expression'
end if    
and this:
Code:
push edi+1    
generates two push instructions. It is related to the tokenization (as in lexical analysis) of source that is done by preprocessor. Strings like "edi+1" or "edi +1" or "edi+ 1" are all tokenized with exactly the same result - three consecutive tokens, "edi", "+" and "1". And then the parser is greedy to see the register operand when it can, so in these three tokens it sees two operands - register and then numerical expression.
So the fact that this:
Code:
db edi+1-edi    
fails is the side-effect of this parsing process, since DB directive sees the register operand, which is not allowed there, and thus fails.

As I wrote earlier, AT and PTR operators (and the square brackets, which are the same thing as PTR) provide a special context where "numerical" expressions starting with registers are allowed. Thus:
Code:
if at eax 4 eqtype at edi+1
 display 'Not anymore!'
end if

label x at edi+1

if at x eqtype at edi+1
 display 'And this one is OK'
end if    


Last edited by Tomasz Grysztar on 04 Dec 2010, 10:46; edited 1 time in total
Post 04 Dec 2010, 10:44
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Rahsennor wrote:
To elaborate, say I want to make a macro that takes an address as an argument. That macro must decide if it can save the address directly with dd or if it must use an alternative encoding. How do I do it?
Win32AX.Inc header uses mov instruction in pushd macro to distinguish kind of address that was given.
Post 04 Dec 2010, 10:45
View user's profile Send private message Reply with quote
Rahsennor



Joined: 07 Jul 2007
Posts: 61
Rahsennor
Merci beaucoup! It makes sense now.

"if at edi+1 eqtype at 1" still passes, making it useless for my purpose. It was a silly purpose anyway. Laughing

@baldr: that is some hack. Nice.
Post 04 Dec 2010, 11:18
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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.

Powered by rwasa.