flat assembler
Message board for the users of flat assembler.
Index
> Compiler Internals > [FASM1] Empty file with virtual as and org |
Author |
|
Tomasz Grysztar 17 Nov 2019, 17:59
By definition, ORG opens a new addressing space (and therefore closes the previous one). In this case is equivalent to doing END VIRTUAL and then VIRTUAL AT 100h.
Because of such semantic problems I changed this in fasmg, where ORG is not allowed inside VIRTUAL. In fasm 1 this option remains only for backward compatibility. |
|||
17 Nov 2019, 17:59 |
|
DimonSoft 17 Nov 2019, 18:38
So, my guess about the reason was right. Now let me argue that such behaviour is not quite consistent. This code
Code: org 100h
end virtual doesn’t compile for very clear reasons: org is documented to start a new addressing space but is NOT equivalent to virtual. For me, logically, unlike virtual which doesn’t let the data pass through to the main output file, org just changes the starting value of the internal address counter. So, I’d say not allowing org inside a virtual block is not really a solution of the semantic problem. Are there any reasons why making org a bit more limited would hurt? My suggestion is as follows: * virtual makes an addressing space (and allows nesting) * org just sets current address counter to a particular value Naming addressing spaces doesn’t seem to work with org, so would not be affected. The only real problem I can see is the meaning of $$ symbol. While I doubt there’s much code out there requiring $$ to point right after the nearest org directive, this seems to be the only concern from semantical point of view, and can safely be left as it is by just using another words: “$$ is always equal to the last explicitly set address, by either org directive or a new virtual block.” I don’t know about actual implementation problems though. Such definition would extend FASM capabilities to produce multiple output files. Say, compiling two or more files from the same source: debug, release, with different ISA requirements (FPU, SSE, etc.). Code: virtual at 0 as 'Debug.exe' ... virtual at 0 as 'Release.exe' ... virtual at 0 as 'NoSSE.exe' ... Not sure about EXEs though (might have problems with format directive). May still be useful for osdev purposes: compiling a separate blob directly into the current project instead of creating intermediate binaries just to use file directive. Last edited by DimonSoft on 17 Nov 2019, 18:45; edited 1 time in total |
|||
17 Nov 2019, 18:38 |
|
Tomasz Grysztar 17 Nov 2019, 18:45
You cannot change current address counter without starting a new addressing space, this is the very nature of what the addressing space is in fasm.
This attribute of addressing spaces is especially important for directives like LOAD and STORE - they need addresses to be unambiguous. This is why you can never LOAD/STORE past the addressing space boundaries, and every directive like ORG or VIRTUAL makes such impassable boundary. As for producing multiple output files, fasmg demonstrates how it can be designed in a clean way - with RESTARTOUT directive. |
|||
17 Nov 2019, 18:45 |
|
DimonSoft 17 Nov 2019, 18:54
Tomasz Grysztar wrote: You cannot change current address counter without starting a new addressing space, this is the very nature of what the addressing space is in fasm. So, is virtual just a “save current state, temporarily change the base, then restore”? Judging from this piece of code Code: org 200h x dd $12345678 org 201h dw $ABCD load a byte from 202h db a Code: 78 56 34 12 CD AB AB Note the addition I made to my original post before seeing your response: there might be valid use cases for allowing org inside virtual blocks. |
|||
17 Nov 2019, 18:54 |
|
Tomasz Grysztar 17 Nov 2019, 19:04
DimonSoft wrote: So the suggestion to allow org inside virtual doesn’t seem to break anything. Note that in your sample you cannot change your LOAD to get a byte from address 200h. You need to label the addressing space to be able to do that. |
|||
17 Nov 2019, 19:04 |
|
Tomasz Grysztar 17 Nov 2019, 19:18
BTW, if you'd be interested how is it possible to assemble multiple executable files with fasmg, here's a quick demonstration:
Code: struc encapsulate? file*, outext:'bin' namespace . catch_postpone include file execute_postponed load OUTPUT:$%% from :0 virtual as outext db OUTPUT end virtual restartout 0 end namespace end struc macro catch_postpone? macro execute_postponed? purge postpone?,end?.postpone? end macro macro postpone? esc macro execute_postponed? end macro macro end?.postpone?! execute_postponed esc end macro end macro end macro User encapsulate 'library_user.asm', 'EXE' Library encapsulate 'library.asm', 'DLL' To get it working with the standard PE formatting macros, POSTPONE emulation would need to be further extended to handle "POSTPONE ?" variant properly (it should be executed after all the regular postponed blocks). |
|||
17 Nov 2019, 19:18 |
|
DimonSoft 17 Nov 2019, 19:22
I see. So, we can define an addressing space as a range of addresses, right? I can formulate my suggestion another way.
Why not allow data from org addressing space to pass through to the outer virtual block (if any) or to the main file output (if no virtual blocks are involved)? Wouldn’t separating these concerns—address calculation and data generation—make more sense than just losing the data? After all, I’d say using virtual has clear intention to not allow data passing through, while in case of org the intention is not there. After all, when people write their bootloaders they might use (at least I saw such examples) org just to change the base address, and the addressing space concept is just something that allows to do it. |
|||
17 Nov 2019, 19:22 |
|
Tomasz Grysztar 17 Nov 2019, 19:28
DimonSoft wrote: Wouldn’t separating these concerns—address calculation and data generation—make more sense than just losing the data? What I just realized, though, is that I never really documented the AS feature in fasm's manual. Turns out I forgot about it and I only have it properly documented for fasmg. |
|||
17 Nov 2019, 19:28 |
|
DimonSoft 17 Nov 2019, 19:35
Tomasz Grysztar wrote: It is just that you started a new addressing space and the AS feature only saves the contents of a single addressing space (this is actually a limitation of fasm 1 engine, even if I wanted to define it differently). Ah, so that’s the problem. Still would it break something if org addressing space started to pass its data to the outer block as if it was normally generated data (while still being an addressing space)? Or is it just too much work to do? I guess, doing it manually with a copy loop and load/store directives would have more impact on compiler memory usage. Not to mention the difficulties loading from addressing spaces that cannot be named. |
|||
17 Nov 2019, 19:35 |
|
Tomasz Grysztar 17 Nov 2019, 19:44
DimonSoft wrote: Ah, so that’s the problem. Still would it break something if org addressing space started to pass its data to the outer block as if it was normally generated data (while still being an addressing space)? Or is it just too much work to do? With fasmg's language definitions this is all a bit cleaner. It defines ORG and SECTION as starting a new area of main output file and this is why you cannot embed them inside a VIRTUAL block (which is an area detached from the main output). DimonSoft wrote: I guess, doing it manually with a copy loop and load/store directives would have more impact on compiler memory usage. Not to mention the difficulties loading from addressing spaces that cannot be named. |
|||
17 Nov 2019, 19:44 |
|
DimonSoft 17 Nov 2019, 20:25
Tomasz Grysztar wrote: I'd see this as conceptually wrong, because the data in the outer block would be seen as being at a different address than the one it is supposed to be at. Piece of code that is supposed to run at different addresses than the main program. It becomes a blob after addresses are calculated anyway. You already have the behaviour of producing a single blob from multiple addressing spaces in plain FASM without virtual blocks, the suggestion is to extend the behaviour to achieve a more useful behaviour. Quote: If you overload ORG with macro, you can give label to every addressing space. It won’t make Code: load a byte from Name:Offset |
|||
17 Nov 2019, 20:25 |
|
Tomasz Grysztar 17 Nov 2019, 20:49
DimonSoft wrote:
DimonSoft wrote:
Code: macro org addr { close_org local area define __AREA area org addr area:: area#.$$ = $$ } macro close_org { match previous, __AREA \{ previous\#.$ = $ \} } org 0 db 'a' org 100h db 'b' close_org irpv area, __AREA { repeat area#.$-area#.$$ load a byte from area : area#.$$+%-1 display a end repeat } |
|||
17 Nov 2019, 20:49 |
|
DimonSoft 17 Nov 2019, 21:06
Tomasz Grysztar wrote:
Oops, my test piece of code didn’t work with namespace labels. I guess, this was due to address values I used. I think, I came up with a good example of task to discuss. Consider writing a set of macros for generating a FAT12 image that allows one to specify both loader code and disk contents, as well as custom values for the boot sector (BPB). The macro set would obviously contain org 7C00h somewhere. Now imagine we want to have this single source generate multiple output files. Say, CoolOS.1.44MB.img, CoolOS.1.2MB.img, etc. If you find FAT12 outdated, let’s think about CoolOS.iso as well. The easy way to do that might have been to wrap the disk definition in virtual at 0 as '1.44MB.img', etc. Another possible task is supporting partitioned media image generation with macros: each volume might have its own boot sector, and there’s also an MBR with code and org directive inside. In its current implementation it seems one has to play around with temporary files and/or multiple projects that basically solve the same task and differ in a few lines of code. |
|||
17 Nov 2019, 21:06 |
|
Tomasz Grysztar 17 Nov 2019, 21:10
DimonSoft wrote: Now imagine we want to have this single source generate multiple output files. |
|||
17 Nov 2019, 21:10 |
|
DimonSoft 17 Nov 2019, 21:22
If only fasmg worked as fast as fasm1…
|
|||
17 Nov 2019, 21:22 |
|
revolution 18 Nov 2019, 16:47
DimonSoft wrote: If only fasmg worked as fast as fasm1… |
|||
18 Nov 2019, 16:47 |
|
Tomasz Grysztar 18 Nov 2019, 17:51
Well, everything comes with a price.
Comparing the two would perhaps be less ridiculous if fasmg had instructions encoders implemented natively (but then it would deserve to be simply called fasm 2) instead of having them in form of complex macros that unroll to hundreds of lines to be interpreted to assemble just a single instruction. But the thing is, even with all that craziness the assembly times still turned out (just barely) bearable enough for my purposes, and I found it very hard to give up this kind of flexibility once I started using it. |
|||
18 Nov 2019, 17:51 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.