| ||
The general format of a macro definition appears as follows :
Name MACRO parameters ... ENDM
Having defined the block once, it is possible to use it multiple times in the program. Depending on the values of the parameters, the section being replaced can take different values. If the specified section is presumed to be reused multiple times for example, within a loop then the macro definition provides indisputable advantages in comparison to a procedure because it speeds up the code execution, for example:
EXC MACRO par1, par2 PUSH par1 POP par2 ENDM
This macro definition will exchange contents between parameters. For example, EXC EAX , EBX is equivalent to PUSH EAX\POP EAX , EXC MEM1 , ESI is equivalent to PUSH MEM1\POP ESI , and so on. Note that if the first parameter is a number, this will load this number into the second operand.
The problem of labels is important with respect to macro definitions. If you use normal labels in macro definitions, then a collision would occur if you use that macro definition more than once. This collision can be avoided by declaring local labels.
To achieve this, the LOCAL keyword is used, for example:
EXC MACRO par1, par2 LOCAL EXI CMP par1, par2 JE EXI PUSH par1 POP par2 EXI: ENDM
This macro definition can be reused as many times as needed, because the assembler will generate a unique label in the course of each substitution.
To exit a macro definition (to stop its generation), the EXITM directive is used. This directive will be, useful if you are using conditional constructs, such as IF ENDIF , in your macro definition.
Now, consider another example of a useful macro.
ustring MACRO quoted_text, ptr_buf LOCAL asc_txt . data asc_txt db quoted_text, 0 .code invoke MultiByteToWideChar, CP_ACP, 0, OFFSET asc_txt, -1, OFFSET ptr_buf, LENGTHOF ptr_buf ENDM
This macro converts the specified ASCII string into the Unicode string and loads it into the buffer pointed to by ptR_buf . In a more general form, this macro will appear as follows:
ustring MACRO quoted_text, ptr_buf LOCAL asc_txt .data asc_txt db quoted_text, 0 .code PUSH LENGTHOF ptr_buf PUSH OFFSET BUF ; Buffer address PUSH -1 PUSH OFFSET asc_txt PUSH 0 PUSH 0 CALL MultiByteToWideChar@24 ENDM
For example, consider the following code fragment:
ustring "Hello!", buf ; Buf --- In data segment PUSH 0 PUSH OFFSET buf PUSH OFFSET buf PUSH 0 CALL MessageBoxW@16 ; Output of the Unicode string
It is convenient ; do you agree?
| ||