flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
Tomasz Grysztar 03 Oct 2016, 18:44
This is the first part of a series where I plan to talk about some unusual and complex trickery that can be done with fasmg. I'm going to deal with problems that I consider too eccentric or difficult to mention in my introduction to fasmg, therefore these texts are going to require an "advanced" level of knowledge about fasmg - please keep the manual at hand.
The other installments: part 2, part 3, part 4. _______ We're going to start with a problem that appears simple on the surface, but it is not. In fasmg the ORG and SECTION directives both begin a new section of output file (they differ only in how they treat the uninitialized data that came before) and to accentuate their function they are not allowed inside a VIRTUAL blocks. Of course, as almost everything in fasmg, this can be adjusted with macros, so let's try it. If what is needed is simply to change the origin address for a portion of virtual block, this classic behavior is easy to emulate with a set of macros that look like this: Code: macro virtual? definition
virtual definition
macro org? address
local addr
addr = address
end virtual
virtual at addr
end macro
end macro
macro end?.virtual?
purge org?
end virtual
end macro But there is also a different scenario, where the specific function of ORG is more apparent and this simple emulation does not help. Let's say that we need to take an entire source of program, like the basic Win32 example from fasmg package, and put it inside a VIRTUAL block, so that we can read the values of symbols defined there without generating actual output (perhaps because we want to output some other data instead). Now this poses a complex problem, because the PE formatting macros not only use ORG and SECTION, but also the values of $% and $%% - the offsets within generated output file. Of course PE format macros could themselves be modified to use only relative offsets (like $-$$), but for the exercise let's say that we want to assemble a foreign source without changing it. We need to provide the correctly computed values of $% and $%% then. The following sample prepares what is necessary to assemble the PE macros inside a VIRTUAL block: Code: virtual at 0 $$% = 0 define $% ($$% + $ - $$) define $%% ($$% + $@ - $$) macro org? address local addr addr = address $$%. = $% end virtual virtual at addr end macro macro section? address local addr addr = address $$%. = $%% end virtual virtual at addr end macro postpone end virtual end postpone include 'win32.asm' Code: macro postpone?! esc macro postponed end macro macro end?.postpone?! postponed esc end macro end macro macro postponed end macro $$% = 0 define $% ($$% + $ - $$) define $%% ($$% + $@ - $$) macro org? address local addr addr = address $$%. = $% end virtual virtual at addr end macro macro section? address local addr addr = address $$%. = $%% end virtual virtual at addr end macro virtual at 0 include 'win32.asm' postponed end virtual Code: $$% = 0 @% = 0 define $% ($$% + $ - $$) define $%% ($$% + $@ - $$ - 1/($@-$$+1)*@%) macro org? address local addr addr = address $$%. = $% @%. = $% - $%% end virtual virtual at addr end macro macro section? address local addr addr = address $$%. = $%% @%. = 0 end virtual virtual at addr end macro macro postpone?! esc macro postponed end macro macro end?.postpone?! postponed esc end macro end macro macro postponed end macro virtual at 0 include 'win32.asm' postponed end virtual purge postpone?,end?.postpone?,org?,section? restore $%,$%% The last variant does handle everything that is needed to "hide" it from the foreign source text that it is assembled inside a virtual block and it even cleans up after itself with PURGE and RESTORE, so any source text that follows can use the ORG and file offsets in their original meaning. The only problem we could still have are the symbol name clashes, and this will be covered in the next part. Last edited by Tomasz Grysztar on 11 May 2017, 13:25; edited 1 time in total |
|||
![]() |
|
Tomasz Grysztar 02 Nov 2016, 08:31
Grom PE wrote: The only way to read the whole output within the program is to do it in multiple chunks, one per each virtual block, correct? Grom PE wrote: It seems faking $ and $$ won't be enough since the address of labels won't be adjusted this way. |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.