Concepts and Types of Macro Nesting
Macro nesting is a powerful code generation technique in assembly language, mainly divided into two forms:
- Macro Call Nesting: Calling other defined macros within the body of a macro definition
- Macro Definition Nesting: Defining new macros within the body of a macro definition
1. Macro Call Nesting
Technical Features
- The called macro must be defined before the macro that calls it
- Supports multi-level calls, forming a macro call chain
- Unfolding starts from the innermost macro and expands layer by layer
Example 1: Hexadecimal Conversion Macro Nesting
; First define the basic conversion macro (convert the low 4 bits of AL to ASCII)
HTOASC MACRO
AND AL, 0FH ; Get the low 4 bits
ADD AL, 90H ; Conversion algorithm
DAA
ADC AL, 40H
DAA
ENDM
; Define the macro that calls HTOASC (process the entire byte of AL)
WHTOASC MACRO
MOV AH, AL ; Save original value
SHR AL, 1 ; Process high 4 bits
SHR AL, 1
SHR AL, 1
SHR AL, 1
HTOASC ; Call sub-macro
XCHG AH, AL ; Swap processed low 4 bits
HTOASC ; Call sub-macro again
ENDM
; Used in the main program
.CODE
MAIN PROC
MOV AL, 3Ah ; Test value
WHTOASC ; Call macro
; At this point AX = 3431h ('4' and '1' in ASCII)
RET
MAIN ENDP
END MAIN
Macro Expansion Process
WHTOASC expands to:
1. MOV AH, AL
2. SHR AL,1
3. SHR AL,1
4. SHR AL,1
5. SHR AL,1
6. HTOASC expands to:
6.1 AND AL,0FH
6.2 ADD AL,90H
6.3 DAA
6.4 ADC AL,40H
6.5 DAA
7. XCHG AH,AL
8. HTOASC expands again as above
2. Macro Definition Nesting
Technical Features
- The inner macro only takes effect after the outer macro is called
- Parameters of the outer macro can be passed to the inner macro definition
- Supports the creation of dynamically generated macros
Example 2: Dynamically Generating Conditional Judgment Macros
; Outer macro: define conditional test macro
DEFMAC MACRO ACNAME, COMP
; Inner macro definition
ACNAME&_IF MACRO VAL, LAB
CMP AX, VAL
J&COMP LAB ; Use outer macro parameter
ENDM
ENDM
; Call outer macro to generate specific comparison macros
DEFMAC ZERO, Z ; Generate ZERO_IF macro
DEFMAC PLUS, G ; Generate PLUS_IF macro
; Use generated macros
.CODE
MAIN PROC
MOV AX, 100
ZERO_IF 0, IS_ZERO ; Expands to: CMP AX,0 / JZ IS_ZERO
PLUS_IF 50, IS_POS ; Expands to: CMP AX,50 / JG IS_POS
JMP CONTINUE
IS_ZERO:
; Handle zero case
RET
IS_POS:
; Handle case greater than 50
RET
CONTINUE:
RET
MAIN ENDP
END MAIN
Macro Expansion Hierarchy
- First expand the
<span>DEFMAC</span>call, creating two new macros:
<span>ZERO_IF</span><span>PLUS_IF</span>
Advanced Application Examples
Example 3: Generating Lookup Table Instruction Sequences
; Define a factory macro for generating lookup macros
GEN_LOOKUP MACRO TNAME
; Inner macro definition
LOOKUP_&TNAME MACRO INDEX, REG
MOV REG, OFFSET TNAME&_TABLE
ADD REG, REG
ADD REG, INDEX ; Assume each entry occupies 2 bytes
MOV REG, [REG] ; Get actual value
ENDM
ENDM
; Define data tables
.DATA
COLOR_TABLE DW 0F00h, 0F80h, 0FF0h, 0F0Fh
SOUND_TABLE DW 440, 494, 523, 587
; Generate lookup macros for specific tables
GEN_LOOKUP COLOR ; Generate LOOKUP_COLOR
GEN_LOOKUP SOUND ; Generate LOOKUP_SOUND
; Use generated macros
.CODE
MAIN PROC
; Use color table
LOOKUP_COLOR 2, BX ; Get the 3rd color value
; Expands to:
; MOV BX, OFFSET COLOR_TABLE
; ADD BX, BX
; ADD BX, 2
; MOV BX, [BX]
; Use sound table
LOOKUP_SOUND 1, CX ; Get the 2nd frequency value
RET
MAIN ENDP
END MAIN
Practical Development Recommendations
-
Modular Design:
- Break down basic functionalities into independent macros
- Build complex functionalities through nested calls
Naming Conventions:
- Use prefixes to distinguish macro levels
- Nested macro names include identifiers from outer macros
Debugging Techniques:
- Use
<span>/Zm</span>option to view macro expansion process - Test each layer of macros in stages
Documentation Comments:
- Add detailed comments for each layer of macros
- Explain parameter passing relationships
Common Problem Solutions
-
Macro Undefined Error:
- Ensure the called macro is defined first
- For nested definitions, ensure the outer macro has been called
Parameter Conflicts:
- Use different prefixes to distinguish parameters at each level
- If necessary, use
<span>&</span>to clarify parameter boundaries
Expansion Results Not as Expected:
- Check operator precedence
- Use
<span><></span>to protect special strings
Macro nesting techniques greatly enhance the abstraction capabilities of assembly language. By designing multi-level macro structures reasonably, it is possible to achieve code reuse patterns similar to high-level languages while maintaining the execution efficiency of assembly. This technique has wide applications in compiler development, system programming, and other fields.