Only the UNIX Assemblers have been traditionally quite poor in macro capabilities, as they have been mostly used as yet another stage for generating code from C compilers.
A good example how to take advantage of such macros is to implement a poor man's compiler, or the first stage of a bootstraped compiler.
Generate bytecodes that can be easily mapped into macros, and then just by having your macro library for the target platform you get the compiler very quickly up and running.
Thankfully in C++ we have constexpr for that.