flat assembler
Message board for the users of flat assembler.
Index
> Main > about fasm macro |
Author |
|
DimonSoft 22 Oct 2018, 15:44
You may want to take a look at prepsrc utility that is provided within FASM package. Compile it and use to analyze how preprocessor sees your progam. The utility takes .fas file as its input and produces a text file as its output. To produce .fas file for your program use Ctrl+F8 if you use FASMW. For me it turned out to be more useful than any explanations in the documentation or this forum. Better once to see than hundred times to hear.
|
|||
22 Oct 2018, 15:44 |
|
Tomasz Grysztar 22 Oct 2018, 15:57
You can use PREPSRC tool that comes with fasm to take a look at lines generated by the preprocessor.
Take this simple source: Code: macro interface name,[proc] { common struc name \{ match , @struct \\{ define field@struct .,name, \\} match no, @struct \\{ . dd ? virtual at 0 forward .#proc dd ? common .\#\\.com.object = name#.com.interface end virtual \\} \} virtual at 0 forward name#.#proc dd ? common name#.com.interface = $ shr 2 end virtual } interface ITest,\ QueryInterface,\ AddRef,\ Release testing ITest I'm going to comment on the text it generates, to explain what it means. First, there is the definition of the macro, it is registered by preprocessor but otherwise left untouched. The lines that went through preprocessor but are not then passed to assembler are preceded with semicolon in PREPSRC output: Code: ;macro interface name,[proc] ;{common ; struc name \{ ; match,@struct \\{ define field@struct .,name,\\} ; match no,@struct \\{ . dd ? ; virtual at 0 ; forward ; .#proc dd ? ; common ; . \# \\.com.object=name#.com.interface ; end virtual \\} \} ; virtual at 0 ; forward ; name#.#proc dd ? ; common ; name#.com.interface=$ shr 2 ; end virtual} Next, there is the line that calls the macro. This is also seen by preprocessor only and not passed to the assembler: Code: ;interface ITest,QueryInterface,AddRef,Release Next, there are lines generated by this instance of the macro. First there are lines that define STRUC-type macro. Note how FORWARD block is processed for every argument in the list: Code: ;struc ITest{ ; match,@struct \{ define field@struct .,ITest,\} ; match no,@struct \{ . dd ? ; virtual at 0 ; ; .QueryInterface dd ? ; ; .AddRef dd ? ; ; .Release dd ? ; ; .#\.com.object=ITest.com.interface ; end virtual \}} Then there are some lines that finally generate something for the assembler. Again, there is a FORWARD block to generate DD line for every argument in the list: Code: virtual at 0 ITest.QueryInterface dd ? ITest.AddRef dd ? ITest.Release dd ? ITest.com.interface=$ shr 2 end virtual Finally, the STRUC-type macro "ITest" is called. This line looks a bit strange, this is because of some quirks of fasm's preprocessor, not important at the moment: Code: ;testing:;ITest The "Itest" macro, as defined above, generates definitions of MATCH blocks, which are in fact a single-use macros: Code: ;match,@struct{define field@struct testing,ITest,} ;match no,@struct{testing dd ? ; virtual at 0 ; testing.QueryInterface dd ? ; testing.AddRef dd ? ; testing.Release dd ? ; testing.com.object=ITest.com.interface ; end virtual} Code: testing dd ? virtual at 0 testing.QueryInterface dd ? testing.AddRef dd ? testing.Release dd ? testing.com.object=ITest.com.interface end virtual |
|||
22 Oct 2018, 15:57 |
|
Step9 22 Oct 2018, 23:11
Thanks very much,this is just what I want.
Thank you. |
|||
22 Oct 2018, 23:11 |
|
Step9 24 Oct 2018, 04:13
But still have a question:
I did follow your instruction,but I can't find how the follow macro works: match , @struct \\{ define field@struct .,name, \\} match no, @struct \\{ . dd ? Can you give me som hints on it ? Thanks |
|||
24 Oct 2018, 04:13 |
|
ProMiNick 24 Oct 2018, 07:44
When line of code located in struct definition variable @struct is defined as blank, outside of struct variable @struct is undefined (value of variable equal to its name).
These lines left macro struct unchanged, but adds ability to declare any struct member as interface. |
|||
24 Oct 2018, 07:44 |
|
Step9 24 Oct 2018, 13:28
Thank you.
But I'm still can not understand clearly. How to make "match , @struct" condition to be true? What's the "@struct" meaning? or how is it defined? |
|||
24 Oct 2018, 13:28 |
|
ProMiNick 24 Oct 2018, 15:06
Code: macro struct name { virtual at 0 define @struct ; @struct is defined here as blank field@struct equ name match child parent, name \{ restore field@struct field@struct equ child,fields@\#parent \} sub@struct equ struc db [val] \{ \common define field@struct .,db,<val> \} struc dw [val] \{ \common define field@struct .,dw,<val> \} struc du [val] \{ \common define field@struct .,du,<val> \} struc dd [val] \{ \common define field@struct .,dd,<val> \} struc dp [val] \{ \common define field@struct .,dp,<val> \} struc dq [val] \{ \common define field@struct .,dq,<val> \} struc dt [val] \{ \common define field@struct .,dt,<val> \} struc rb count \{ define field@struct .,db,count dup (?) \} struc rw count \{ define field@struct .,dw,count dup (?) \} struc rd count \{ define field@struct .,dd,count dup (?) \} struc rp count \{ define field@struct .,dp,count dup (?) \} struc rq count \{ define field@struct .,dq,count dup (?) \} struc rt count \{ define field@struct .,dt,count dup (?) \} macro db [val] \{ \common \local anonymous define field@struct anonymous,db,<val> \} macro dw [val] \{ \common \local anonymous define field@struct anonymous,dw,<val> \} macro du [val] \{ \common \local anonymous define field@struct anonymous,du,<val> \} macro dd [val] \{ \common \local anonymous define field@struct anonymous,dd,<val> \} macro dp [val] \{ \common \local anonymous define field@struct anonymous,dp,<val> \} macro dq [val] \{ \common \local anonymous define field@struct anonymous,dq,<val> \} macro dt [val] \{ \common \local anonymous define field@struct anonymous,dt,<val> \} macro rb count \{ \local anonymous define field@struct anonymous,db,count dup (?) \} macro rw count \{ \local anonymous define field@struct anonymous,dw,count dup (?) \} macro rd count \{ \local anonymous define field@struct anonymous,dd,count dup (?) \} macro rp count \{ \local anonymous define field@struct anonymous,dp,count dup (?) \} macro rq count \{ \local anonymous define field@struct anonymous,dq,count dup (?) \} macro rt count \{ \local anonymous define field@struct anonymous,dt,count dup (?) \} macro align \{ \local anonymous define field@struct anonymous,align, \} macro union \{ field@struct equ ,union,< sub@struct equ union \} macro struct \{ field@struct equ ,substruct,< sub@struct equ substruct \} } Code: macro ends { match , sub@struct \{ restruc db,dw,du,dd,dp,dq,dt restruc rb,rw,rd,rp,rq,rt purge db,dw,du,dd,dp,dq,dt purge rb,rw,rd,rp,rq,rt purge union,struct,align irpv fields,field@struct \\{ restore field@struct \\common define fields@struct fields \\} match name tail,fields@struct, \\{ if $ display 'Error: definition of ',\\`name,' contains illegal instructions.',0Dh,0Ah err end if \\} match name=,fields,fields@struct \\{ restore @struct ; here @struct defined again to not blank undefined state make@struct name,fields define fields@\\#name fields \\} end virtual \} match any, sub@struct \{ tmp@struct equ field@struct restore field@struct field@struct equ tmp@struct> \} so ... here @struct value will be =@struct Code: ;after use of macro struct, variable @struct became blank struct MYSTRUC a interface IUnknown ; interface will be declared as member of MYSTRUC ;after use of macro ends, variable @struct restored to previos value, in our case again to undefined state equal to =@struct ends ... here @struct value will be again =@struct Code: a interface IClassFactory ; here interface will be declared as is |
|||
24 Oct 2018, 15:06 |
|
Step9 24 Oct 2018, 20:35
Thank you very much.
|
|||
24 Oct 2018, 20:35 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.