flat assembler
Message board for the users of flat assembler.
Index
> Main > Design Principles, or Why fasm Is Different Goto page 1, 2 Next |
Author |
|
MazeGen 03 Mar 2005, 18:14
Thanks, Privalov, we can now know all important about fasm (and what we can expect) from one article
|
|||
03 Mar 2005, 18:14 |
|
JohnFound 03 Mar 2005, 19:28
Good article (hm, maybe little not finished ). And great principles. The SSSO is exactly what I expect from any compiler, not only assemler.
Regards |
|||
03 Mar 2005, 19:28 |
|
Tomasz Grysztar 03 Mar 2005, 21:17
Yes, I think I should expand at least the fifth section a bit.
What do you think about the idea of adding it to the "Documentation" section after it's "more" finished? |
|||
03 Mar 2005, 21:17 |
|
JohnFound 03 Mar 2005, 21:45
Privalov wrote: What do you think about the idea of adding it to the "Documentation" section after it's "more" finished? Definitely, yes. Do you have some doubts? It is very important document. Regards. |
|||
03 Mar 2005, 21:45 |
|
decard 03 Mar 2005, 23:04
Maybe even a link in main index... this article would make less people post similar questions on the board
|
|||
03 Mar 2005, 23:04 |
|
khanh 03 Mar 2005, 23:47
sorry, I may be stupid but still don't understand the self-dependent source part you explained. Why the block
Code: if ~ defined alpha | defined_here alpha: defined_here = 1 end if need to be assembled again (since it's already assembled one time). |
|||
03 Mar 2005, 23:47 |
|
JohnFound 04 Mar 2005, 00:32
Hm, after some meditation on the "defined" directive I failed to solve following problem: Let say I have two libraries and every of them uses 'EDIT' controls. So, I want to use only one string constant with the class name EDIT. How to define this string in both libraryes with the same name "cEditClassName" the way that to avoid conflicts when I use one of the libraries or both together included in random order?
The trick mentioned above works once, but not twice: Code: ; in first library if ~ defined cEditClassName | defined_here cEditClassName db 'EDIT',0 defined_here = 1 end if ; in second library if ~ defined cEditClassName | defined_here cEditClassName db 'EDIT',0 ; symbol already defined error. defined_here = 1 end if If I try to use different names for "defined_here": Code: ; in first library if ~ defined cEditClassName | defined_here cEditClassName db 'EDIT',0 defined_here = 1 end if ; in second library if ~ defined cEditClassName | defined_there ; undefined symbol error cEditClassName db 'EDIT',0 defined_there = 1 end if Maybe the solution is simple, but I failed to see it...maybe it's time to sleep Regards |
|||
04 Mar 2005, 00:32 |
|
Tomasz Grysztar 04 Mar 2005, 05:53
khanh: it needs to be assembled again because it uses the values of some symbol before they are defined, so their values were predicted - one more pass is required to check whether all predictions match with the resulted values.
JohnFound, here's the correct solution: Code: if ~ defined cEditClassName | defined here cEditClassName db 'EDIT',0 here = 1 end if ; in second library if ~ defined cEditClassName | defined there cEditClassName db 'EDIT',0 there = 1 end if or alternatively: Code: if ~ defined cEditClassName | defined_here cEditClassName db 'EDIT',0 defined_here = 1 else defined_here = 0 end if ; in second library if ~ defined cEditClassName | defined_there cEditClassName db 'EDIT',0 defined_there = 1 else defined_there = 0 end if I have also corrected the example I have given in the article, since the problem you had was because of my mistake. Last edited by Tomasz Grysztar on 04 Mar 2005, 06:06; edited 1 time in total |
|||
04 Mar 2005, 05:53 |
|
revolution 04 Mar 2005, 06:05
And it can be put into a macro
Code: macro new_string name,string { local here if ~ defined name | defined here name db string here = 1 end if } new_string cEditClassName,<'EDIT',0> ;some code new_string cEditClassName,<'EDIT',0> ;more code new_string cEditClassName,<'EDIT',0> |
|||
04 Mar 2005, 06:05 |
|
MazeGen 04 Mar 2005, 07:55
Quote:
It could be interesting to note how it was done in previous versions of MASM (I guess up to 5.1): there was two levels of directives like IF, ELSEIF etc., i.e. IF1, IF2, ELSEIF1, ELSEIF2: Code:
IF2
IFNDEF var
EXTRN var:far
ENDIF
ENDIF2 I personally think such approach is more convenient than definying yet another constant. BTW, since MASM 6.1, there's no need to these levels, MASM can solve it, so the source is much more clear. OTOH, it is very powerful feature of the assembler if the coder can know which pass is the assembler performing. For instance, you can expand some macros only in the first pass or only in the second pass and make very nice tricks. |
|||
04 Mar 2005, 07:55 |
|
Tomasz Grysztar 04 Mar 2005, 10:26
Allowing to dig inside the resolving scheme like this would break its main aims - it's up to assembler to resolve the source and any ingerentions into this process can only cause a mess with its logic. I prefer fasm's approach with defining additional constant just because it's a clear logical structure. The "if not defined then it's defined" approach leads to an antynomy and this is how fasm sees it. Any tring to simplify source by allowing such constructs breaks the logic and is a "dirty" solution from my point of view.
The specifics of fasm's code resolving are that the conditions can link to each other and the way some parts of code are assembled might happen to be frequently changing from pass to pass - for this any pass-number-based conditions are completely unusable. |
|||
04 Mar 2005, 10:26 |
|
tom tobias 04 Mar 2005, 10:54
"Of course this text is far from being complete in terms of describing the design of flat assembler. But it shows the main directions and should be enough to explain most of the choices I've been doing. Anyway the reason behind this all is also that I'm keeping the flat assembler project as "one man's vision", stressing the efforts to keep the overall logic and consistency. I hope this text will help others to understand my motives and vision itself."
Thank you, good start. |
|||
04 Mar 2005, 10:54 |
|
Tomasz Grysztar 04 Mar 2005, 20:23
I have updated the FAQ in the Documentation section and put there this text aswell. Also the extended programmer's manual for fasm 1.59 is coming soon.
|
|||
04 Mar 2005, 20:23 |
|
MCD 09 Mar 2005, 14:10
Whooa, finally, you SAID it
|
|||
09 Mar 2005, 14:10 |
|
revolution 18 Mar 2005, 01:22
So the preprocessor/assembler separation is why the following does not compile?
Code: repeat 20 call @f dd % @@: end repeat Gives "Error: symbol already defined" Is there an elegant solution to this? I don't like to use constructions like: Code: repeat 20 call $+9 dd % end repeat Too many problems can be introduced by changing the "dd %" line and forgetting to change the "call $+9" above to match. |
|||
18 Mar 2005, 01:22 |
|
Tomasz Grysztar 18 Mar 2005, 05:39
revolution wrote: So the preprocessor/assembler separation is why the following does not compile? It's just the simple fact that "repeat" is processed by assembler, and therefore it operates on the same labels each time. So redefition problems etc. come into sight. Some partial solution might be: Code: @@: repeat 20 jmp $+size dd % if % = 1 size = $ - @b end if end repeat but only assuming that the size of repeated data is constant. For backward references it can be done better. And for a full solution, the newly implemented "rept" directive is the one: Code: rept 20 % { call @f dd % @@: } After all, "rept" is a try to make such things possible in features the architecture, which was designed with quite different priorities. If I had to write fasm again (I might consider writing some 2.0, though not in the near future, definitely) I would design it again from scratch to become more "intuitive" in such cases. I think I would make it do the passes on the whole preprocessing/assembling loop, so affecting preprocessor features with label-value depenent conditionals would be possible, etc. This combined with ability to make macros by macros would give it some LISP-like power; yes - it might be slower (though not much in cases, where only a few passes would be needed), but much more powerful. In fact, I already have much of such assembler design in my mind, but I don't feel I would dedicate my time to such demanding (and non-commercial at the same time) project in any near future. Last edited by Tomasz Grysztar on 12 Jun 2005, 09:20; edited 1 time in total |
|||
18 Mar 2005, 05:39 |
|
khanh 08 Jun 2005, 14:09
I think there is a simpler solution existing for the self-dependence souce as Privalop explained:
Quote: if ~ defined alpha | defined_here in the 1st pass, the symbol table resolved "but it also can ignored those defined in the condition express" (if, if not....) so you don't need to implement a trick to walk around this. It could also work well with the twice-implementation as someone proposed. It sound may be odd but please tell me if I am wrong. |
|||
08 Jun 2005, 14:09 |
|
Tomasz Grysztar 08 Jun 2005, 14:27
Please explain better what exactly do you mean.
|
|||
08 Jun 2005, 14:27 |
|
khanh 08 Jun 2005, 17:52
Let me give an example:
For the code: Quote: if ~ defined alpha If in the 1st pass, all the symbols and labels are established except the those defined inside the If conditional statement, hence the alpha label is unknown if it is not defined outside this block yet. In the second pass, it will attempt to resolve this block by concentrating only in the conditional block; by using the table builded by the early pass, so if alpha is defined, it will ignore this statement, otherwise it will define label alpha. For the problem found by Johnfound. Quote:
It can be simply done like this: Quote:
Suppose that the cEditClassName is not defined anywhere else outside these two blocks, so in the second pass, as I explained earlier, the first block will define cEditClassName (and added to the label table), so the second block is ignored as it already defined earlier, this gives away the error of redifinition of variable. When I said "ignored", I mean the parser will "jump" to resolve the code after the ending code "end if" since it does not need to care whatever inside this conditional statement. As the result, to solve this, one more pass may be needed to correct the problem. I don't know if this conflicts with your internal design of Fasm, but if it is implemented, we can overcome the ambiguous cases occur. Since the assembler had better to be designed to reflect what human thinks ( the logic) and to me when I write "if" (if anything), then I mean "anything" fact must be known (or must be defined "above" that). I hope this is clear for you. Sorry for my bad english. PS: if I understand correctly from your context, the 1st pass or lexical analysis the labels, symbols, and keywords are found so this gives them 1st priority, but sometime the control directive "if", for example, may need to give it higher priority than the above, than this case applies into the problem. |
|||
08 Jun 2005, 17:52 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.