The Macros Basics .
Redefining the Mnemonics
As there is no concept of ''Reversed Words'', in RosAsm, one great feature of RosAsm is that you can redefine mnemonics just like any common macro symbolic:
[push | push #1 | #+1] ; macro declaration
push eax, ebx, ecx ; macro evocation
>>> push eax | push ebx | push ecx ; unfolding of upper macro evocation
In the upper Declaration #1 means 'Parameter Number One'. But this '1' is 'moveable', this is to say that, when the Macro Parser will unfold the Macro Evocation, it will, in this case, replace this '1' by '1', '2', '3' while unrolling the Macro Loop.
#+1 means 'repeat all previous Macro Declaration Statements (as many times as transmitted parameters), and add 1 to all 'moveable' parameters at each loop'.
This macro does not generate an infinite loop. So, you can entirely redefine your own memonics use rules.
Note: Infinite loops are not completely impossible:
[mov | mov #2 #1]
mov eax, ebx >>> mov ebx eax
>>> mov eax ebx ;.... and so on
Of course, RosAsm detects such cases.
Cascading unknown numbers of parameter.
[call | push #L>2 | call #1]
The #L>2 means 'from Last to second Parameter'. With this convention, you can write Macros that will assume any number of Parameters, including no Parameter, at all
call 'USER32.MessageBoxA' &NULL, Message, Title, &NULL
>>> push &NULL, title, message, &NULL | call 'USER32.MessageBoxA'
and, if upper 'Push' is defined >>> push &NULL | push Title | push Message
push &NULL | call 'USER32.MessageBoxA'
If no parameter is transmitted for 'push #L>2', no problem: It allows any parameters number, in this case, including none:
call MyProcedure esi, edi
call MyRoutine
Nesting Macros Evocations
In the previous example, the 'push #L>2' is a nested Evocation.You can nest Macros Evocations levels up to a limit. of... 255. This limit is useful to keep control upon infinite loops:
[fill_with | mov #2 #F | #+1]
[clear | fill_with 0, #1>L]
clear eax ebx ecx
>>>
fill_with 0, eax ebx ecx
>>>
mov eax 0 | mov ebx 0 | mov ecx 0
Controlling the Parameters number
There is a simple way to ensure that your evocations will have the required number of Parameters, if this verification is desirable in some macros: You can force the Macros Parser to control this, with '| #=4 |. For example:
[CommonColorBits | #=4 | and #F #2 | #+1]
CommonColorBits eax, ebx, ecx, edx ; OK.
CommonColorBits eax, ebx, ecx ; Compile >>> Error: Missing Parameter.
In all other cases, when this is possible RosAsm controls the number of parameters in the evocation (expressed parameters numbers), even if you don't ask for it with some '| #=4 |', for example:
[mov | mov #1 #2 | #+2]
mov eax ebx, ecx edx
>>>
mov eax ebx | mov ecx edx ; OK.
mov eax, ebx, ecx ; >>> error 'missing parameter in macro evocation'
Looking at what the Macros Parser does
If you want to see what RosAsm does with one of your Macro Evocations, just DoubleLeftClick upon the Evocation name to open the Floating Menu, and choose the [Unfold] Option. A Dialog Box will appear, with an Edit Control showing the results outputted by the Macro Parser. Your statement is always preceded by a Dummy label, useful in case of Local Symbols (this feature does not search for what possible upper main Label).
In this second release of the Macro Unfolder, all of the possible nested Macros and Equates are properly computed. This makes it, of course much slower than the previous simplified version, but usage did show that the lack of Equates parsing made it of little help in several complex cases, as it is difficult for users to understand in which order the various Parsers do their respective jobs. So, it is worthy waiting a couple of seconds when working with huge files, and much better than not fully understanding what is going on with complex Macro unfoldings, when hunting for hidden bugs.
~~~~~~~