Inside Macros .
Local Labels inside Macros
In many cases, you will find the need of declaring Local Labels inside your Macros Declarations. This may be a problem if you do not take care of choosing non-conflicting Local Labels Characters. I recommend that you reserve 'L' (L1,.... L9) for usual code Local locations with a very short scope. For simple Macros, that cannot conflict with others, I recommend the use of the 'M' Character. For all HLL Organization Macros, that could generate naming conflicts, the best way is to reserve one Character per Macro.
Example of organization Macro, using the 'O' Char for 'On':
[On | cmp #1 #3 | jn#2 O9> | #4>L | O9: ] ; jn#2 >>> jna
; #4>L allow any length statement
On eax > ebx, xchg eax ebx
>>> cmp eax ebx | jna O9>
xchg eax ebx
O9:
In case this chunk of code would be included inside a larger HLL organization flow, for example, an If or a Select_Case group, as long as the If reserved Character will be 'I' (or 'C' for Case, and so on), there will be no problem of Local Labels naming conflicts.
Nesting Declarations inside Macros
You can use Macros to declare Equates, Data, or even other Macros. Example:
[Proc3 | Proc#1 | push ebp | mov ebp esp | {#1! | %=3 | push %L>1 | call Proc#1!} ]
Inside the nested Declaration, '{ }' are substitutes to '[ ]', and '%' is a substitute to '#' when you do not mean the first level parameters but the nested level parameters. See an example of this complex macro running in Beginner's Tut 5.
With '{ }' substitutes, you can declare Macros, Data and Equates inside Macros Declarations. Inside '{ }', '%' is a substitute of '#'. Example:
[FirstMacro | ... | {Included#1 | mov %1 #2} ]
FirstMacro MacroName 32
...
IncludedMacroName eax
will be unfolded as:
mov eax 32 ; (MOV TO 'IncludedMacro first parameter', 'FirstMacro second parameter').
Upper %1 is replaced only at 'IncludedMacro' evocation, and #2 immediately at 'FirstMacro' evocation.
Example of C_like Data Declarations:
[POINT | {#1: #1.x: D$ 0 #1.y: D$ 0}]
[MSG | {#1: #1.hwnd: D$ 0 #1.message: D$ 0 #1.wParam: D$ 0
#1.lParam: D$ 0 #1.time: D$ 0} POINT #1.Point]
MSG MyMsg
mov D$MyMsg.Point.X 0A | mov D$MyMsg.Point.Y 010
Or with integrated initialization:
[POINTi | {#1: #1.x: D$ #2 #1.y: D$ #3}]
[MSGi | {#1: #1.hwnd: D$ #2 #1.message: D$ #3 #1.wParam: D$ #4
#1.lParam: D$ #5 #1.time: D$ #6} POINTi #1.Point #7 #8]
MSGi MyMsg 0 0 0 0 0 0A 010
Hexprint D$MyMsg.Point.X | Hexprint D$MyMsg.Point.Y
~~~~~~~