I've read somewhere about being macro mad.
You'll now discover what it means to be macro PERVERT.

Prologue/Epilogue Extender (or P/E Extender for short) is a set of macros which primarily allows to access procedure arguments and local variables through esp rather than ebp, thus freeing ebp for common use (and also preserved register).

Well-- primarily it was that. Until today, its list of features grew longer and longer, and it was time to update some of the documentation to make it ready for publication.

Note that P/E Extender is currently in RC2 state, and performs quite stable, nevertheless, any bugs go into this thread, or directly to s-m-k@gmx.net.

--------------------------------------------------------------------------

Prologue/Epilogue Extender for Masm v2.0-RC2
a high-level macro compilation for low-level coders

Copyright ? 2000, 2001 ?SMK? <s-m-k@gmx.net>

LEGAL NOTICE - The author accepts no responsibility for losses of any type
arising from the use of this macro set. Whereas the author has used his best
endeavours to ensure that this compilation of macros is working, you should
not rely on this and you should do your own tests.

In other words: Make backups.
--------------------------------------------------------------------------


FEATURES

    [*] Enables generation of stack pointer (esp) based stack frames, provides all necessary offset calculation for procedure arguments and local variables via text macro equations
    [*] Support for Masm standard base pointer (ebp) based stack frames:
    * Enabling the use of _alloca (growable-only memory allocation on the stack, rather than using heaps. Library code included with P/E Extender)
    * Enabling the possibility to align the stack pointer (ie. local variables that need an alignment other (bigger) than DWORD)
    [*] Built-in support for structured exception handlers
    [*] Full support for PASCAL, BASIC and FORTRAN languages
    [*] Optimized alignment techniques for local variables allocation:
    * Native data types are automatical naturally aligned
    * If the size of any local type is bigger than 4 bytes, the stack will be suitably aligned to the biggest type (results in loss of ebp, this functionality can be disabled)
    * Optional enforced alignment
    [*] Extensive debug and trace message modes, smart error handling


    KNOWN ANOMALIES

      [*] Within one module (ie. file), all symbolic names of any P/E Extender enabled procedure (argument and local names) have to be unique!
      Technical background: Once a symbol is made into an equation, there is no possibility to re-define the same name to another equation (or purge it). Workaround: Prefix symbolic names with abbrevated procedure name.
      [*] All macro directives spanning more than one line must use line continuation '\'! (Masm macro limitation)
      [*] Since there is no 'fatal error' macro command, it is not possible to immediately stop the compiler. Therefore I've chosen to issue two error messages per error: One is issued in compiler flow, (sometimes) with additional verbose information appended (like faulty arguments, etc.). The other is a Masm .ERR, which appears always at the end of all compiler messages (not in compiler flow).


      Included in ZIP:
      peext.mac - Main macro include file
      peext.txt - Rough documentation of new directives and options
      \alloca - Library and source of _alloca support
Posted on 2001-07-28 18:55:01 by -SMK-
SMK,

I had a look to your macros and some tests done. And I dare to say that only very few people will use it. Ok, I must admit that it works principially. But:

- include a code example! It is really needed. For you I think it looks very simple. But others who are not used to this stuff will resign.
- just to get one free register the coder must accept to care for unique names on source code level AND modify source code at many places (_push, _pop). Too much costs.
- the stuff is not foolproofed. For example, if you need to do a push without a pop in a loop (.repeat or .while), your macros will not work.

May be a "precompiler" solution would be better, if any.

japheth
Posted on 2001-07-29 09:45:49 by japheth
japheth:

Just to get one free register the code must accept to care for unique names on source code level AND modify source code at many places (_push, _pop).

I see that point, and especially for the unique names, I must admit it's one of the biggest unsolved problems I have (and no alternative solution, as of yet). On the other hand, I primarily use P/E Extender to write optimized subroutine/library code containing time critical hot spots - most of them from scratch - and do not convert whole existing programs. Think of it: What would you gain from? One more common usage register between tons of Win32 API (or in general - subroutine) calls. That isn't what I made it for, and efforts for conversion go far beyond any realistic performance/algorithmic gains.

Modification of code isn't a thing I really have to care about. Any editor should be able to search and replace text within a selection (with the procedure of interest currently selected ;)).

The stuff is not foolproofed. For example, if you need to do a push without a pop in a loop (.repeat or .while), your macros will not work.

I completely agree with you: you found something that isn't possible - and was never meant to be (I think I concerned about the given example in the answer above). Besides that: Can you give me a real-life example that makes it necessary to push/pop a number of values, where the number is known only at run-time (and further, that is not able to be translated into a similar algorithm)? Or, according to what I said before: Hot spots souldn't contain such push/pop 'orgies' - refer to execution times of these instructions.

BTW, workaround: Since you know the space required for the looped push operation at least at run-time, you can use the included _alloca command to allocate as much space as you need on the stack, and do a .repeat / mov (which executes way faster, too). Note that _alloca requires an ebp-based stack frame. Be creative, it's all in there...!

Last, not least: examples. I know, I know... It's time to write a basic outline of all supported functions, and the resulting code. Stay tuned...
Posted on 2001-07-29 12:17:30 by -SMK-
-SMK-

quote:
--------------------------------------------------------------------------------

Besides that: Can you give me a real-life example that makes it necessary to push/pop a number of values, where the number is known only at run-time (and further, that is not able to be translated into a similar algorithm)?
--------------------------------------------------------------------------------

Ok, I agree that my example is no real problem. But the following pseudo code:

count = 0
.repeat
push value
value = parent(value)
inc count
.until value = 0

.while (count)
pop value
do something useful with it
dec count
.endw

will hopefully show that pushing values repeatedly in a loop can be a proper solution to handle tree data structures for example. But you are right, you will always be able to code it in another way.

japheth
Posted on 2001-07-30 09:05:22 by japheth