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


~~~~~~~