flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > [fasmg] pe.inc : data types override

Author
Thread Post new topic Reply to topic
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 07 Apr 2017, 10:17
I'm a bit lost with overriding data types in pe.inc.
Code:
macro dword? value
    ;display '+'
    local v
    v = value
    if ~ v relativeto 0 & v relativeto PE.RELOCATION
        store $-PE.IMAGE_BASE:dword at PE.relocated_addresses:PE.RELOCATION_INDEX shl 2
        store IMAGE_REL_BASED_HIGHLOW:word at PE.relocation_types:PE.RELOCATION_INDEX shl 1
        dd v - PE.RELOCATION
        PE.RELOCATION_INDEX = PE.RELOCATION_INDEX + 1
    else
        dd v
    end if
end macro

macro dd? definitions&
    iterate value,definitions
        match ?, value
            dd ?
        else match n =dup? ?, value
            dd n dup ?
        else match n =dup? (?), value
            dd n dup ?
        else match n =dup? v, value
            repeat n
                dword v
            end repeat
        else
            dword value
        end match
    end iterate
end macro

struc dd? definitions&
    label . : dword
    iterate value,definitions
        match ?, value
            dd ?
        else match n =dup? ?, value
            dd n dup ?
        else match n =dup? (?), value
            dd n dup ?
        else match n =dup? v, value
            repeat n
                dword v
            end repeat
        else
            dword value
        end match
    end iterate
end struc
    

These overrides are needed to build relocations table. That is what I understand. However, it seem I don't fully understand how overrides work. Let's add
Code:
display '+'
    

to dword macro

Now, how I understand it, if I do dd 1, the flow is: macro dd > macro dword > built-in dd?? and + is displayed once.

But if I do dword 1, the flow seems to be macro dword > macro dd > macro dword >built-in dd?? because + is displayed twice.

How comes it doesn't get stuck in recursion?
Post 07 Apr 2017, 10:17
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 07 Apr 2017, 10:26
zhak wrote:
But if I do dword 1, the flow seems to be macro dword > macro dd > macro dword >built-in dd?? because + is displayed twice.

How comes it doesn't get stuck in recursion?
For the same reason that "dd" does not recurse. You can ignore the initial "macro dword >" layer and "macro dd > macro dword > built-in dd" is just the regular way how instruction re-definition works in fasm and fasmg. Every built-in instruction becomes a variable symbol when you re-define it.

This "dword" macro was not supposed to be used directly, to avoid excess calls like in your example it would be better to make "dword" macro use "emit" instead of "dd".
Post 07 Apr 2017, 10:26
View user's profile Send private message Visit poster's website Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 07 Apr 2017, 12:02
So, it "digs down" in redefinitions.

Still the following doesn't make sence to me:
Code:
macro dword? value
  display '11 '
  dd value
end macro

macro dword? value
  display '12 '
  dd value
end macro

macro dword? value
  display '13 '
  dd value
end macro

macro dd? value
  display '01 '
  dword value
end macro

macro dd? value
  display '02 '
  dword value
end macro

dword 1
    

The above does dword 13 > dd 02 > dword 12 > dd 01 > dword 11 > built-in dd, which is correct. Now, if remove dword 13, an error occurs because dword 12 > dd 02 > dword 11 > dd 01 > no more dword defined.
The same applies if reduce further: remove macro dd 02 - works, then remove macro dword 12 - error.

So, dword must be defined times dd defined + 1, in general. But this doesn't apply to the case when both dword and dd are defined once (as in original pe.inc example) -- it works instead of generating an error. Maybe it is silly things I ask, but why exactly does this happen?
Post 07 Apr 2017, 12:02
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 07 Apr 2017, 12:09
When "dword" is defined just once, it is not variable and therefore allows recursion. So when "dd" is called from "dword" and it in turn calls "dword", it calls the same "dword" macro, not a previous version like in the case when instruction is variable.
Post 07 Apr 2017, 12:09
View user's profile Send private message Visit poster's website Reply with quote
zhak



Joined: 12 Apr 2005
Posts: 501
Location: Belarus
zhak 07 Apr 2017, 12:12
It's clear now. Thanks a lot.
Post 07 Apr 2017, 12:12
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 07 Apr 2017, 12:14
I think that when you say "variable", it means the same as "overloaded" in HLL speak. i.e. same name but different code.
Post 07 Apr 2017, 12:14
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 07 Apr 2017, 12:27
The "overload" happens when you define a symbol in the child namespace with the same name as one in the parent/global namespace. In fasmg these two mechanisms can be combined in different ways. You can have the overloading symbol in child namespace be variable while still having non-variable global one. For example if you have a variable "dd" macro defined in nested namespace and it calls the "dd" macro recursively, it is going to finally call "dd" in the parent namespace, and if that macro is not variable, it may proceed with a true recursion. You also may have a non-variable macro in local namespace and then it may call itself recursively, resulting in a complete overload of a global macro.

Generally in fasm term "variable symbol" means one that has no single universally accessible value, and therefore cannot be forward-referenced (nor self-referenced, as in case of recursion). The "overloading" happens when there are symbols with the same name but in different namespaces and one takes precedence over the other.
Post 07 Apr 2017, 12:27
View user's profile Send private message Visit poster's website 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.