SPRUI03E June 2015 – January 2023
The macro language supports recursive and nested macro calls. This means that you can call other macros in a macro definition. You can nest macros up to 32 levels deep. When you use recursive macros, you call a macro from its own definition (the macro calls itself).
When you create recursive or nested macros, you should pay close attention to the arguments that you pass to macro parameters because the assembler uses dynamic scoping for parameters. This means that the called macro uses the environment of the macro from which it was called.
Using Nested Macros shows nested macros. The y in the in_block macro hides the y in the out_block macro. The x and z from the out_block macro, however, are accessible to the in_block macro.
in_block .macro y,a
. ; visible parameters are y,a and x,z from the calling macro
.endm
out_block .macrox,y,z
. ; visible parameters are x,y,z
.
in_block x,y ; macro call with x and y as arguments
.
.
.endm
out_block ; macro call
Using Recursive Macros shows recursive and fact macros. The fact macro produces assembly code necessary to calculate the factorial of n, where n is an immediate value. The result is placed in the A1 register . The fact macro accomplishes this by calling fact1, which calls itself recursively.
.fcnolist
fact1 .macro n
.if n == 1
MVK globcnt, A1 ; Leave the answer in the A1 register.
.else
.eval 1, temp ; Compute the decrement of symbol n.
.eval globcnt*temp, globcnt ; Multiply to get a new result.
fact1 temp ; Recursive call.
.endif
.endm
fact .macro n
.if ! $iscons(n) ; Test that input is a constant.
.emsg "Parm not a constant"
.elseif n < 1 ; Type check input.
MVK 0, A1
.else
.var temp
.asg n, globcnt
fact1 n ; Perform recursive procedure
.endif
.endm