flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > recursive macro

Author
Thread Post new topic Reply to topic
shutdownall



Joined: 02 Apr 2010
Posts: 517
Location: Munich
shutdownall 06 Aug 2017, 18:50
Hi,
I wanted to create a macro extending standard PUSH and POP instructions in my Z80 version of FASM in a simple way:

Code:
macro push [char] {
      if char in <all>
       push AF BC DE HL IX IY
;       push exx 
;       (throws error in this definition)
      else if char in <exx>
       EXX
       push BC DE HL
       EXX
      else
       push char
      end if
}
    


This works if I use single register names in any choice or the keywords all or ext. ext simply saves the additional registers (double set of BC/DE/HL). If I combine the keyword all with additional save of the extension registers push exx it does not work.
It gives "push exx" as illegal instruction (commented out in the above example).

If I call push exx directly, it works as expected. Isn't it possible to combine all with ext without defining the subset of registers double ? Isn't it possible to use macros recursive this way ?

Any other suggestions ?
Post 06 Aug 2017, 18:50
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20531
Location: In your JS exploiting you and your system
revolution 06 Aug 2017, 20:34
If you define the macro twice you can call it up to twice before you get back to the native definition of push.

But you can also define the macro within itself so that you can do infinite recursion (if wanted/needed).
Post 06 Aug 2017, 20:34
View user's profile Send private message Visit poster's website Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 517
Location: Munich
shutdownall 06 Aug 2017, 20:59
revolution wrote:

But you can also define the macro within itself so that you can do infinite recursion (if wanted/needed).


Can you please help how to do that ?
Post 06 Aug 2017, 20:59
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20531
Location: In your JS exploiting you and your system
revolution 06 Aug 2017, 21:06
Look for the win32ax.inc file in the windows download, and inside there look at the allow_nesting macro for pushd/invoke. It allows infinite nesting of invoke.
Post 06 Aug 2017, 21:06
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8367
Location: Kraków, Poland
Tomasz Grysztar 07 Aug 2017, 13:47
If you tried to use such trick to make this macro recursive, you would end up with infinite recursion (not a good thing, obviously), because you use assembly-time conditionals while macro expansion is done entirely in the preprocessing stage. You'd need to change your IF blocks into MATCHes and then the recursion could be viable (but still would require a trick with macro redefinition).

I really would recommend switching to fasmg for this kind of macros.
Post 07 Aug 2017, 13:47
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20531
Location: In your JS exploiting you and your system
revolution 07 Aug 2017, 15:42
There is also the trick in fasm1 of using uppercase letters to access the native implementation directly.
Code:
macro push ... {
   Push ...  ;invoke the native push directly with an uppercase P
}    
Post 07 Aug 2017, 15:42
View user's profile Send private message Visit poster's website Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 517
Location: Munich
shutdownall 07 Aug 2017, 22:47
Tomasz Grysztar wrote:

I really would recommend switching to fasmg for this kind of macros.


Thanks for your info about it. I thought that macros could be called recursively in general but did not thought quite deep about it - it was more or less a question. I could also live with two macros or with double code in one macro, in general try to avoid double code if possible.

Code:
macro push [char] {
      if char in <all>
       push AF BC DE HL IX IY
       EXX
       push BC DE HL
       EXX
      else if char in <exx>
       EXX
       push BC DE HL
       EXX
      else
       push char
      end if
}
    


Switching to fasmg is not an alternative for me right now for this small feature. I can live with double code and bigger macros, not that big problem. And there is not more than 2 stages ("push all" calls "push exx").

Anyway thanks for all comments. Wink
Post 07 Aug 2017, 22:47
View user's profile Send private message Send e-mail 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.