Macros may redefine themselves. In recursive instances, the macro must contain a conditional directive that will terminate the recursion. When a macro is redefined (or when it redefines itself), the previous definition is supplanted by the current one. Macros may invoke themselves recursively. Consider the factorial function, implemented as a recursive macro: .macro factorial INT .if \INT factorial (\INT-1) F = F * \INT .else F = 1 .endc .endm We encourage you to trace the effect of invoking this macro with a small value of INT, such as 4. The final value of the symbol F could be shown by using it in a mov instruction: .auto factorial 4 mov r14 = F .default In this case, the mov instruction will assemble with an immediate constant of 24. The .exitm directiveThe .exitm directive can be used to exit unconditionally from further expansion of a macro. The .exitm directive exits just one level of macro expansion (for nested macros). This directive is useful in implementing case structures (i.e., mutually exclusive conditions). The .err directiveThe .err directive can be used to mark a position in a macro that should be logically unreachable. When the assembler encounters this directive, it prints an error message. It also inhibits the production of an object file unless the -Z option was specified on the gcc command line. The following sketch of a case structure illustrates how the .exitm and .err directives can be used: .macro choice WHEN .if (\WHEN > 1984) // case for FUTURE .exitm .endc .if (\WHEN == 1984) // case for THAT YEAR .exitm .endc .if (\WHEN == 1983) // case for YEAR BEFORE .exitm .endc .if (\WHEN < 1983) // case for earlier .exitm .endc .err // Should never assemble this line .endm Since the enumerated cases are exhaustive for all calendar years, the .err directive should not be encountered. |