flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > How to know macros was used already?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
In my opinion I have to save or declare the name of used macros then check if it was declared before.
Code:
MacroName#declared    

That means I have to redesign macro itself
Code:
macro red_macro [param] {
   ... here I have to take the name of some used macro form first position in Param
   ... but there is not comma in use after the name, I trying to:
   c=0
   nextParam=
   irps arg , <Param> \{
      c=c+1
      if c=1
         MacroName=_name
         arg#defined=TRUE
      else
         nextParam=`nextParam+','+arg
      end if
   \} 
   macro MacroName [nextParam] \{
      ... this is my macros can I declare the body just right here or not?
   \}
}
macro fix red_macro
...
purge macro
    

If I redesign the macro how to declare a body of used macros?
Post 20 Aug 2020, 12:50
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17624
Location: In your JS exploiting you and your system
revolution
There is a problem with mixing of assembler and preprocessor.

= is an assembler construct so the macro doesn't see it.

To count things in the preprocessor this might help:
https://board.flatassembler.net/topic.php?p=215081#215081
Post 20 Aug 2020, 12:57
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
How this works in includes?
Code:
macro proc [args]
 { common
    match name params, args>
    \{ define@proc name,<params \} }
    

Can you explain this code please?
Post 20 Aug 2020, 13:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17624
Location: In your JS exploiting you and your system
revolution
Overclick wrote:
How this works in includes?
Code:
macro proc [args]
 { common
    match name params, args>
    \{ define@proc name,<params \} }
    

Can you explain this code please?
It extracts the name and adds <> around the trailing arguments.
Post 21 Aug 2020, 02:49
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
Can I use the same way to save macro names when it was used?
Post 21 Aug 2020, 15:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17624
Location: In your JS exploiting you and your system
revolution
I'm not 100% sure what you want to achieve, but I don't see why you couldn't use something like that.
Post 22 Aug 2020, 00:08
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
I need to check if macros in use already or not. I mean I have to save every single name of usual macros declared after my trick-code. That why I need fake macro2
For example:
Code:
macro macro2 [param] {
   macro param \{ ??? \}
}
macro fix macro2

macro Ret {
   ret 0      ;How to move this body to redesigned (fake)macro2 directive?
}
    


Look at my first message I showed some thinks about the way to get the name of macro to be saved when used. I need to do something like that to make some changes for calling macros. I need to know if it's in use already or not to make desigion. The best way is to save its name with some identifier and chek if that name already defined or not. Then define it if it's first time.
This identifiers needed for preprocessing stage only. Not for compiled code.
My questions is:
1) How to better take the name of called macros? By irsp or I have to use match? Then how?
2) Have I stick it by # or @ how it works?
3) How to declare the body of next coming macros inside that fake macro? I understand how to hold it's one lined arguments but never seen how to redirect it's full body.
You say before that combination of macro macro is possible by fix. But I mean to keep its functionality. Not destroy macro forever and use it's name as last declared macro )) I need to add my trick functionality to it and let it be as usual macro directive almost as before.

Do you know another trick to keep the name of called macro without "macro macro" combination?
Post 22 Aug 2020, 10:19
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17624
Location: In your JS exploiting you and your system
revolution
Do you mean like this?
Code:
macro a {nop} ; okay
macro b {int3} ; okay
macro a {hlt} ; does nothing because 'a' is already declared above    
Post 22 Aug 2020, 10:28
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
I'm not talking about declaration to use for. It needs to be single declaration. I need to define deployments.
Code:
 
macro a {if used nop  else ret end if}
a    ;translated as ret
a    ;translated as nop    

a is not my macro. it is any macro. I need it's name only even if it's fake macro or cascade of macros needed.
Code:

macro macro2 [param] {
        ;get name as first in Param
        ;stick it with some key as name@defined
        if defined name@defined
           purge name
           nop
        else 
           define name@defined
           <<<Is any chance to declare the 'macro a' here as it is?>>>
        end if
         }
macro fix macro2

macro a {ret}

a    ; ret
a    ; nop

    
Post 22 Aug 2020, 12:50
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17624
Location: In your JS exploiting you and your system
revolution
So you want a wrapper around macro expansion.

I can see how to place a prefix like if, but not a suffix like end if.

Also a macro can't purge itself.
Code:
macro a {
        nop
}
macro a {
        ret
        purge a ;purges nop above
}
a       ;ret
a       ;ret
purge a ;purges ret
a       ;error    
Post 22 Aug 2020, 13:04
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
In that example macro doesn't purge itself as it is macro2(renamed to macro). The 'name' to be purged is inside Param at that moment. 'a' as followed.

I need to expand macro macro or take it's name 'macro' for temporary use Sad
Is there any other option to take the macros names without touching them directly?
I don't know what of name it will be 'a' or 'b' etc. Macros.inc will be included after modification.

Seems I have to forget about macro modification and try to use gimp sticks inside own section directives. That code will not be beautiful...
Post 22 Aug 2020, 14:29
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 807
Location: Belarus
DimonSoft
It’s not really clear what you’re asking for but it seems you want some means to know whether particular macro is defined at some point in your code, no matter by whom. It’s possible but only to some extent:
Code:
; Magic macro setup

macro define_macro Params&
{
  match name rest , Params
  \{
    macro_list equ name
    macro_defined@ \# name equ 1
    rept 0 \\{
  \}
  match name , Params
  \{
    macro_list equ name
    macro_defined@ \# name equ 1
  \}
  macro Params
}

macro fix define_macro



; Put any other macro definitions here
; NOTE! The { character should be on a separate line!

macro test1
{ db 42 }

macro test2
{ db 44 }

; Macros may be invoked as usual

test2
test1



; Get the list of macros defined at this point

display 'List of defined macros:', 13, 10
irpv item , macro_list
{
  display `item, 13, 10
}

; Check if particular macro has been defined

match =1 , macro_defined@test1 { display '`test1` macro has been defined.', 13, 10 }
match =1 , macro_defined@test2 { display '`test2` macro has been defined.', 13, 10 }    

Note that this solution requires that opening curly brace is at the next line. There’s no solution for the general case, at least I got no response asking the question in this topic. The limitation is from the way curly brace gets treated by the preprocessor, it’s easily seen with PREPSRC. Note that even standard proc32.inc and other macro includes do not satisfy the requirement.

Obligatory note: If you share the bigger problem you’re trying to solve, there might be an easier solution. To me the idea of intercepting every macro definition (even the ones not under your control) is asking for trouble since you never know what expectations of which macro such solution might break. If you’re trying to build some kind of module/unit support, letting each module “register” itself might be a better idea with an easier solution.
Post 22 Aug 2020, 20:33
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
This is exactly what I need. Did you try match ={, in your case? Did you try as Tomasz said? Did you try fix it?


I need to check if macros used for my updated .multisection trick. Now it works in proc and macros just fine but I want to add much extended support for macros as:
Code:
macro some
{
  .data once
    <<adds global data once>>
  .data ifexist
    <<adds additional global data if macro was used before>>

... same way for all directives

  .code
    call some_proc
    local ..next
    jmp ..next
  .code once
    proc some_proc
      .data once
      .code once
      .data once
      .code once
    endp
  .idata once
  .code
    ..next:
  .code ifexist
    ...
}
    

Just don't tell me I will mix or loose global variables. Nobody loose it in masm for example. Nobody loose it in fasm when macros used to declare some variables instead of code. This trick will let me and other to create subprograms and procedures on the fly without need to search for required elements somewhere in huge sections.
Now you know what I want to do with macro names )
https://board.flatassembler.net/topic.php?t=21545
Should be updated some day.
Post 23 Aug 2020, 05:31
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 807
Location: Belarus
DimonSoft
Overclick wrote:
This is exactly what I need. Did you try match ={, in your case? Did you try as Tomasz said? Did you try fix it?

Tomasz replied after I wrote my previous comment, so no, I haven’t yet. The idea suggested there is cool but I personally will probably stay with a more limited solution I have for my projects for a while since the solution really is “too insane” and will decrease the readability of PREPSRC output for my case.

Overclick wrote:
I need to check if macros used for my updated .multisection trick. Now it works in proc and macros just fine but I want to add much extended support for macros as:
Code:
macro some
{
  .data once
    <<adds global data once>>
  .data ifexist
    <<adds additional global data if macro was used before>>

... same way for all directives

  .code
    call some_proc
    local ..next
    jmp ..next
  .code once
    proc some_proc
      .data once
      .code once
      .data once
      .code once
    endp
  .idata once
  .code
    ..next:
  .code ifexist
    ...
}
    

If I get the goal right, I implemented something similar. But I ended up wrapping pieces that need to be gathered throughout the source code in uniquely named macros. Their generation is wrapped up with constructs like these:
Code:
code
{
  ...
}

data
{
  ...
}

...    
and the generated macros are automatically added to the appropriate lists and invoked when it’s time to finally put the code/data. The only difference is that it doesn’t have a Pascal-like section-like syntax. Solvable but not in a reliable enough way (for me).

Yet I managed to avoid the need to make a list of all the macros. First of all, even the solution we have by now doesn’t prevent defining a macro before everything is set up. So I ended up letting macro definitions everywhere (and it’s quite a valid assumption that I will need to define a “temporary” macro some day) and just wrap code and data to be postponed. So the problem of { placement only relates to the code, data and a few other such macros for me.
Post 23 Aug 2020, 10:19
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
When I created multisection macro I was thinkin same way to use macros for sections. But needed { } stopped me. Now I haven't any begin...end markers. Use my one, don't be shy ))
Post 23 Aug 2020, 11:18
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7781
Location: Kraków, Poland
Tomasz Grysztar
With FIX directive you can easily hide the braces. For a demonstration purposes I wrote a simple example just now:
Code:
.data FIX } macro _data { _data
.code FIX } macro _code { _code
.end FIX } _data

macro _data { _code }   ; put all code pieces before the data
macro _code {           ; start with _code macro open

; example follows (here a simple 16-bit DOS program):

        org     100h

.data
        hello   db 'Hello!',13,10,36

.code
    show:
        mov     ah,9
        mov     dx,hello
        int     21h

.data
        counter db 3

.code
        dec     [counter]
        jnz     show
        int     20h
.end    
Note how ".code" and ".data" hide all the braces needed to close the previous macro and open the next one.

PS. If you were using fasmg instead, its unconditional macros serve the same role as fasm's FIX.
Post 23 Aug 2020, 11:42
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: 17624
Location: In your JS exploiting you and your system
revolution
Tomasz Grysztar wrote:
With FIX directive you can easily hide the braces.
Yeah, but that suffers from the problem of instructions that use the braces {}, they need to be escaped.
Post 23 Aug 2020, 11:47
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7781
Location: Kraków, Poland
Tomasz Grysztar
revolution wrote:
Tomasz Grysztar wrote:
With FIX directive you can easily hide the braces.
Yeah, but that suffers from the problem of instructions that use the braces {}, they need to be escaped.
Yeah, I don't even keep that in mind, since fasmg has mostly got rid of these issues.
Post 23 Aug 2020, 11:50
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
My solution is the best at the moment (ovation) Smile Only one little problem is needs to be run in separate file. Any way nobody needs multisections in small projects. IDE from template creates few files...
Post 23 Aug 2020, 13:17
View user's profile Send private message Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 197
Overclick
DimonSoft, I fixed your example:
Code:
macro define_macro Args&
{
  Params equ Args
  match name rest , Params
  \{
    macro_list equ name
    macro_defined@ \# name equ 1
    rept 0 \\{
  \}
  match name , Params
  \{
    macro_list equ name
    macro_defined@ \# name equ 1
  \}
  macro Args
}

macro fix define_macro    

Now I have little bit harder quest, I need to do the same for macros defined inside another macros. This one just skips them.
Post 24 Aug 2020, 22:53
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< 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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.