flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > Some basic macros for fasm g |
Author |
|
Tomasz Grysztar 13 Jul 2016, 17:05
Another simple macro that I use for the compatibility with fasm 1 is the one that allows to use anonymous labels. This feature is not implemented into fasm g - the reason is that it was so often requested to provide various enhancements of this feature, that I decided it is better to keep it in form of macro that can then be customized to one's liking. And the basic implementation is really very plain:
Code: macro @@ tail
match label, @f?
label tail
@b? equ @f?
end match
local anonymous
@f? equ anonymous
end macro
define @f?
@@ |
|||
13 Jul 2016, 17:05 |
|
shoorick 14 Jul 2016, 09:25
he-he exactly after I have rewritten all my 8080 projects to exclude all "@@" labels they are returning
i made this fake subroutine to test some conditions: Code: macro @@ tail match label, @f? label tail @b? equ @f? end match local anonymous @f? equ anonymous end macro define @f? global: jmp .ttt .back: lxi h,100 @@: dad h jnc @B ret .ttt: jmp .back Code: Error: symbol '@B' is undefined or out of scope. +++++++++++++++++ my fault! i should add this also: Code: define @f? @@ ; <<<!!!!! i supposed it was a kind of example |
|||
14 Jul 2016, 09:25 |
|
Tomasz Grysztar 14 Jul 2016, 13:57
shoorick wrote: he-he exactly after I have rewritten all my 8080 projects to exclude all "@@" labels they are returning |
|||
14 Jul 2016, 13:57 |
|
shoorick 06 Sep 2016, 14:05
I have collected some known to me macros into the single zip
_________________ UNICODE forever! |
|||||||||||
06 Sep 2016, 14:05 |
|
Tomasz Grysztar 16 Oct 2016, 16:52
I have started working on conversions of other macros from fasm's standard Windows headers, and here comes the conversion of PROC32.INC:
Code: macro stdcall? proc*,args& match any, args iterate arg, args indx 1+%%-% pushd arg end iterate end match call proc end macro macro ccall? proc*,args& local size size = 0 match any, args iterate arg, args indx 1+%%-% pushd arg size = size + 4 end iterate end match call proc if size add esp,size end if end macro macro invoke? proc*,args& stdcall [proc],args end macro macro cinvoke? proc*,args& ccall [proc],args end macro prologue@proc equ prologuedef macro prologuedef procname,flag,parmbytes,localbytes,reglist local loc loc = (localbytes+3) and (not 3) parmbase@proc equ ebp+8 localbase@proc equ ebp-loc if parmbytes | localbytes push ebp mov ebp,esp if localbytes sub esp,loc end if end if match any, reglist iterate reg, reglist push reg end iterate end match end macro epilogue@proc equ epiloguedef macro epiloguedef procname,flag,parmbytes,localbytes,reglist match any, reglist iterate reg, reglist indx %%-%+1 pop reg end iterate end match if parmbytes | localbytes leave end if if flag and 10000b retn else retn parmbytes end if end macro close@proc equ macro proc? statement& local _local,params,flag,regs,parmbytes,localbytes,current,tmp,initlocal macro endp?! localbytes = current purge ret?,locals?,endl?,LOCAL match close:reglist, close@proc,<regs> close name,flag,parmbytes,localbytes,reglist end match end namespace end if end match purge endp? end macro match name declaration, statement if used name name: namespace name match =stdcall? args, declaration define params args flag = 11b else match =stdcall?, declaration define params flag = 11b else match =c? args, declaration define params args flag = 10001b else match =c?, declaration define params flag = 10001b else define params declaration flag = 0 end match define regs match =uses? list, params define params list while 1 match =, tail, params define params tail break else match reg tail, params define params tail if % = 1 regs equ reg else regs equ regs,reg end if else break end match end while end match virtual at parmbase@proc match args, params iterate arg, args match argname:type, arg label #argname:type rb type else #arg dd ? end match end iterate end match parmbytes := $-(parmbase@proc) name#% = parmbytes/4 end virtual match prologue:reglist, prologue@proc:<regs> prologue name,flags,parmbytes,localbytes,reglist end match macro ret? operand match any, operand retn operand else match epilogue:reglist, epilogue@proc:<regs> epilogue name,flag,parmbytes,localbytes,reglist end match end match end macro current = 0 macro initlocal local area,pointer,length,value area:: pointer = localbase@proc+current length = $@ - (localbase@proc) - current current = $ - (localbase@proc) end virtual while length > 0 if length < 2 load value:byte from area:pointer mov byte [pointer],value pointer = pointer + 1 length = length - 1 else if length < 4 load value:word from area:pointer mov word [pointer],value pointer = pointer + 2 length = length - 2 else load value:dword from area:pointer mov dword [pointer],value pointer = pointer + 4 length = length - 4 end if end while virtual at localbase@proc+current end macro macro locals? virtual at localbase@proc+current macro ? line& line if $ > $@ initlocal end if end macro end macro macro endl? purge ? initlocal end virtual end macro macro LOCAL args& locals iterate arg, args match varname[count]:type, arg varname dbx type:count dup ? else match varname:type, arg varname dbx type, ? else match varname[count], arg varname rd count else arg dd ? end match end iterate endl end macro end macro Some notes on the differences between this implementation and fasm's original
|
|||
16 Oct 2016, 16:52 |
|
rCX 15 Jan 2017, 05:29
Tomasz Grysztar wrote: Another simple macro that I use for the compatibility with fasm 1 is the one that allows to use anonymous labels. This feature is not implemented into fasm g - the reason is that it was so often requested to provide various enhancements of this feature, that I decided it is better to keep it in form of macro that can then be customized to one's liking. And the basic implementation is really very plain: Really excited to learn about fasm g Please be patient with my dumb questions as I haven't coded in fasm in 6 years. So I'm trying to understand how the @@ macro works. Basically you define a macro named "@@" with parameter "tail". From the documentation I understand that everything between "match" and "end match" is only assembled if "label" is "@f" or "@F". I know that in fasm g "label" is a keyword used to define a label, but here you are matching it with @f. So is "label" a variable here? Also why do you have to define "@f?" before "@@"? |
|||
15 Jan 2017, 05:29 |
|
Tomasz Grysztar 15 Jan 2017, 10:14
rCX wrote: So I'm trying to understand how the @@ macro works. Basically you define a macro named "@@" with parameter "tail". From the documentation I understand that everything between "match" and "end match" is only assembled if "label" is "@f" or "@F". I know that in fasm g "label" is a keyword used to define a label, but here you are matching it with @f. So is "label" a variable here? Also why do you have to define "@f?" before "@@"? So when "@f?" is defined initially with an empty value, that block is skipped the first time. But then "@f?" is re-defined with a new value and it become a symbolic link to a local "anonymous" label. Then the next "match label, @f?" assigns "anonymous" as a value to "label" parameter and executes the block. At this point we have two parameters - "tail" with the value like ":" (or any other construction that followed "@@" in the line that called the macro) and "label" with value "anonymous". The line "label tail" becomes (during the preprocessing) "anonymous :", and this is then interpreted as a definition of "anonymous" label. In fasm LOCAL created a new unique name for each such label, with fasmg this works a bit differently - the name is always the same, but it carries the context in which it was defined (that's why I used the term "symbolic link", you may find more information on this in one of the advanced tutorials that I wrote [relatively] recently). |
|||
15 Jan 2017, 10:14 |
|
rCX 17 Jan 2017, 03:09
Thanks for the explanation. I think I understand it now.
|
|||
17 Jan 2017, 03:09 |
|
zhak 18 Jan 2017, 20:17
Hmmm struct macro is pretty simple, indeed. But what if struct contains another struct and that one contains another? initializing them as name:value would be a pain in the ass. Also, this macro doesn't allow passing sequences of values like in:
Code: struct MY a rb 4 ends my MY <1,2,3,4> |
|||
18 Jan 2017, 20:17 |
|
Tomasz Grysztar 18 Jan 2017, 21:09
zhak wrote: But what if struct contains another struct and that one contains another? initializing them as name:value would be a pain in the ass. Code: struct POINT x dd ? y dd ? ends struct RECTN topleft POINT bottomright POINT ends area RECTN topleft.x:0,topleft.y:0, bottomright.x:320,bottomright.y:200 zhak wrote: Also, this macro doesn't allow passing sequences of values (...) |
|||
18 Jan 2017, 21:09 |
|
Tomasz Grysztar 20 Feb 2017, 15:35
The IRPS directive of fasm 1 has no equivalent in fasmg - because there were a few different variants of it that could be implemented and I have not decided which one of them to choose (similarly to how I did not implement "@@" internally because there are many different variants of it that are better implemented as macros that can be chosen according to preference). But it is possible to make a macro implementing a variant very similar to the original:
Code: macro irps?! parameter*, text& local block,buffer macro irps?.process purge irps?.process define buffer text while 1 match car cdr, buffer define buffer cdr block car else match any, buffer block any end match break end match end while end macro esc macro block parameter& end macro macro end?.irps?! esc end macro irps?.process end macro Code: irps a, sum=x+y display `a,13,10 end irps Code: macro with? parameter*, value& local block macro end?.with?! esc end macro purge end?.with? block value end macro esc macro block parameter& end macro macro irps?! parameter*, text& local buffer,symbol define buffer text while 1 match car cdr, buffer define symbol car define buffer cdr else match any, buffer define symbol any end match break end match end while irpv sym, symbol with parameter, sym end macro macro end?.irps?! end with end irpv end macro Code: irps a, sum=x+y display `a,' (',`%,'/',`%%,')',13,10 end irps |
|||
20 Feb 2017, 15:35 |
|
Tomasz Grysztar 31 Mar 2018, 20:12
With the introduction of new OUTSCOPE directive into fasmg the implementation of IRPS becomes much more natural:
Code: macro irps?! parameter*, text& local buffer,symbol define buffer text while 1 match car cdr, buffer define symbol car define buffer cdr else match any, buffer define symbol any end match break end match end while outscope irpv parameter, symbol end macro macro end?.irps?! end irpv end macro Also, another tweak allows to unroll IRPS only conditionally, which has many advantages: Code: macro irps_as_irpv? parameter*, text& local buffer,symbol define buffer text while 1 match car cdr, buffer define symbol car define buffer cdr else match any, buffer define symbol any end match break end match end while outscope irpv parameter, symbol end macro macro irps?! arguments& macro irpv! purge irpv end macro irpv outscope irps_as_irpv arguments end macro macro end?.irps?! end irpv end macro |
|||
31 Mar 2018, 20:12 |
|
shoorick 11 Nov 2018, 07:59
well, I put my hands on hobby coding after another long delay and found @@ does not work for me again...
the latest fasmg version says while including this macro: Code: flat assembler version g.ibh5n Hello, world! hello.asm [6]: @@: macro @@ [6] macro equ [4]: . = value Processed: . = anonymous Error: symbol 'anonymous' is undefined or out of scope. -- it works in clean source with only "db", but does not work with 8051.inc: Code: include "include/@@.inc" include "8051.inc" display "Hello, world!" db 0,0,0,0 @@: db 0,0,0,0 db @F db @B db 0,0,0,0 @@: db 0,0,0,0 |
|||
11 Nov 2018, 07:59 |
|
Tomasz Grysztar 11 Nov 2018, 08:53
The problem here is that 8051.inc alters the meaning of EQU, and this can break any macros that use it. In this case it should be enough to replace EQU with DEFINE in @@ macro, but in general - to make 8051.inc operate with various standard macros - this re-definition of EQU should perhaps be done differently.
|
|||
11 Nov 2018, 08:53 |
|
shoorick 11 Nov 2018, 09:35
I also have supposing it is around "TT equ P1.3" situation, but was not sure
If it will work with DEFINE it should be enough, but I failed to do it by myself I wrote: Code: macro @@ tail
match label, @f?
label tail
define @b? @f?
end match
local anonymous
define @f? anonymous
end macro
define @f?
@@ Code: include "include/@@.inc" include "8051.inc" display "Hello, world!" mov R1,#10 @@: xch A,B djnz R1,@B jmp $ Code: flat assembler version g.ibh5n Hello, world! hello.asm [8]: djnz R1,@B macro DJNZ [11]: offset = -($+2)+addr Processed: offset = -($+2)+@B Error: symbol 'anonymous' is undefined or out of scope. _________________ UNICODE forever! |
|||
11 Nov 2018, 09:35 |
|
Tomasz Grysztar 11 Nov 2018, 13:52
DEFINE does not expand symbolic values like EQU does, taking this into account the modified version should be:
Code: macro @@ tail
match label, @f?
label tail
define @b? label
end match
local anonymous
define @f? anonymous
end macro
define @f?
@@ |
|||
11 Nov 2018, 13:52 |
|
shoorick 11 Nov 2018, 15:34
thanks! now it works! i love these labels!
|
|||
11 Nov 2018, 15:34 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.