flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > FASMG definite operator & passes: question for you Tomasz

Author
Thread Post new topic Reply to topic
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 07 Mar 2025, 12:48
Hi Tomasz,

pls see below snippet
Code:
if definite A
        display 'A DEFINITE', 13 , 10
else
        display 'A NOT DEFINITE', 13 , 10
end if

A = 1
    


=> I see fasmg needs 2 passes to resolve this, and only 1 if i remove last statement (A = 1).
... really looks odd to me ...
... somehow feels like in first pass, fasmg assumes A not definite earlier - which is obviously true and certain at this point - this can't ever be invalidated under any circumstances
... then sees it defined later, so then needs another pass to confirm it was not really defined earlier ... as if somehow A cud be fwd referencing sthg
... really can't make sense of this... the whole purpose of definite is to check that something doesn't exist yet w/o fwd ref
... I fail to see why 2nd pass should ever be required ...

Can you pls give me your view on this ?
Post 07 Mar 2025, 12:48
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 07 Mar 2025, 13:20
Even before the DEFINITE operation is done, there is registered prediction of "A" being not defined, it happens when checking for EQU replacements. When "A" later becomes defined, this is recognized as misprediction, even though the value is not symbolic, because fasmg has not enough flag granularity to be able to distinguish these cases. The simplest way to see this effect is:
Code:
x equ A ; perceived misprediction disappears if you change EQU to DEFINE, even though they have the same effect otherwise
A = 1    
It is one of the flaws in fasmg's implementation, but usually of little consequence.
Post 07 Mar 2025, 13:20
View user's profile Send private message Visit poster's website Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 07 Mar 2025, 16:35
hmm ... ok thx for feedback

wud u then shed light on another one pls :
1/
Code:
isdef = 0

irpv __, A
        isdef = 1
        break
end irpv


if ~isdef
        A = 1
end if
    


2/
Code:
isdef = 0

irpv __, A
        isdef = 1
        break
end irpv


if ~isdef
        A = X + Y

        X = 1
        Y = 2
end if
    



=> snippet 1/ needs only 1 pass ... apparently showing irpv not impacted by same effect as definite ...
... BUT snippet 2/ requires 3 passes ...
... would have expected only 2 = 1 extra vs 1/ due to fwd ref in definition of A ... ?
... what is happening there ?
Post 07 Mar 2025, 16:35
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1066
Location: Russia
macomics 07 Mar 2025, 20:10
fabbel wrote:
=> snippet 1/ needs only 1 pass ... apparently showing irpv not impacted by same effect as definite ...
... BUT snippet 2/ requires 3 passes ...
... would have expected only 2 = 1 extra vs 1/ due to fwd ref in definition of A ... ?
... what is happening there ?

1) isdef = 0 -> A = X?fwd + Y?fwd, X = 1, Y = 2-> next pass
2) isdef = 1 -> no A?, no X?, no Y? -> next pass
3) isdef = 0 -> A = 1 + 2 = 3 -> done
Post 07 Mar 2025, 20:10
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 07 Mar 2025, 20:35
sorry but i don't get it.... irpv state shud not change in pass 2) ...
irpv never fwd ref, and A is only defined LATER in source... so shud see no impact there
and irpv block shud still let isdef as intially defined = 0
Post 07 Mar 2025, 20:35
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 07 Mar 2025, 20:38
... otherwise same wud apply for snippet 1/ which shud imply 2 passes i/o 1 pass only
Post 07 Mar 2025, 20:38
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 07 Mar 2025, 20:56
.. i might be wrong of course and let Tomasz revert on this...
but as I see it :
... irpv supopsedly uses variable name only, not an expresssion ... and it sees text 'A' purely as an identifier in 'iprv __, A' ,
... this shud involve no text substitution, and shud not generate any assumption about potential existence / absence of item A at exec time, because A is not the result of an evaluation
... as such, there is no term in there whose existence / absence cud potentially be invalidated later... precisely bec no eval involved and consequently no furter iteration required
Post 07 Mar 2025, 20:56
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1066
Location: Russia
macomics 07 Mar 2025, 22:04
https://flatassembler.net/docs.php?article=fasmg_manual#11 wrote:
The "irpv" is another repeating instruction and an iterator. It has just two arguments, first being a name of parameter and second an identifier of a variable.
On the first pass, the identifier of a variable named A is not defined (forward reference: it remains to be solved on the next pass), and on the second pass (after if ~isdef on first pass), it will be defined and irpv will trigger by creating the string isdef = 1, which will prevent the creation of the identifier A on pass 2, which will require pass 3.
Post 07 Mar 2025, 22:04
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 08 Mar 2025, 00:23
yes but still....
the manual also states :
Quote:

It iterates through all the stacked values of symbolic variable, starting from the oldest one (this applies only to the values defined earlier in the source)


... how comes snippet 1/ needs only 1 pass ?
1/
Code:
isdef = 0

irpv __, A
        isdef = 1
        break
end irpv


if ~isdef
        A = 1
end if
    
Post 08 Mar 2025, 00:23
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 08 Mar 2025, 00:29
... Tomasz previously commented

Quote:

IRPV is a very good solution, even if a bit tricky. It detects all kinds of values and never forward-references.


in this post:

https://board.flatassembler.net/topic.php?p=228117#228117
Post 08 Mar 2025, 00:29
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1066
Location: Russia
macomics 08 Mar 2025, 02:17
Well, look at that. In your example, there is a conditional definition for A. 1 additional pass (2nd) is needed to understand where this definition of A is relative to irpv, and the second to solve the forward references in the expression of this A
Post 08 Mar 2025, 02:17
View user's profile Send private message Reply with quote
fabbel



Joined: 30 Oct 2012
Posts: 92
fabbel 08 Mar 2025, 07:55
... I appreciate your contribution, but sorry again, this fails to explain snippet 1/ above
... it is exactly as you say: * irpv block on identifier A, * followed by conditionnal def of A
and yet, it runs in only 1 pass... try it...
the reason for this - as I see - is, again, precisely because iprv never fwd-ref ...
... so when famsg meets irpv on identifier A, it does'nt need to wait to resolve it from further source.... there is no need to "understand where this definition of A is"
... all that matters to irpv is that A wasn't given any value in earlier source, and that's all it takes into account
... so irpv simply does nothing.. nothing to resolve any further / no fwd-ref involved
... and the later conditional def on A has no further impact, simply bec. again, irpv is only impacted by source that precedes it.
Post 08 Mar 2025, 07:55
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 08 Mar 2025, 08:40
Even when the value of the symbol is not forward-referenced, the resolution of the identifier may still cause a prediction, for example decision whether to interpret symbol as case-sensitive or case-insensitive variant (or whether to use symbol from the parent namespace) may be affected by predictions:
Code:
define A? a
define B? b

irpv _, A       ; identifier A refers to case-insensitive symbol, because case-sensitive one is never defined
        display `_
end irpv

irpv _, B       ; identifier B refers to case-sensitive symbol (consistently across all possible uses)
        display `_
end irpv

define B bb    
Therefore, while IRPV never uses forward-referencing for values, it still uses predictions for symbol identifier resolution, because this process follows the same rules across all uses of such identifier.

If you keep digging, you may find numerous examples where fasm is overzealous in taking additional passes. The fundamental rule is that the final assembly needs to be correct, and taking additional pass to ensure it is less of a problem than failing to notice an inconsistency. When the information available is not precise enough to be sure whether something really changed from the predictions, assembler always takes the safe route. And sometimes having more precise information would mean too much bloat for the engine - it is a balancing act that required many sleepless nights from me.
Post 08 Mar 2025, 08:40
View user's profile Send private message Visit poster's website 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.