Detailed Explanation of Macro Definition Nesting Techniques in Assembly Language

Concepts and Types of Macro Nesting

Macro nesting is a powerful code generation technique in assembly language, mainly divided into two forms:

  1. Macro Call Nesting: Calling other defined macros within the body of a macro definition
  2. 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

  1. First expand the<span>DEFMAC</span> call, creating two new macros:
  • <span>ZERO_IF</span>
  • <span>PLUS_IF</span>
  • Then expand the calls to these new macros
  • 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_&amp;TNAME MACRO INDEX, REG
            MOV REG, OFFSET TNAME&amp;_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

    1. 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

    1. 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.

    Leave a Comment