汇编:宏汇编、宏库

宏定义与宏调用

宏汇编的核心优势是宏(Macro) —— 将重复代码封装为自定义指令,简化编程。

1. 宏定义语法

宏名 MACRO [参数1, 参数2,...]
    ; 宏体(汇编指令)
    [EXITM]  ; 可选:提前退出宏
ENDM

2. 宏示例

示例 1:无参数宏(打印换行)
; 定义宏:打印回车+换行
PRINT_NEWLINE MACRO
    PUSH AX  ; 保护寄存器
    PUSH DX
    MOV AH, 02H  ; DOS中断02H:显示单个字符
    MOV DL, 0DH  ; 回车
    INT 21H
    MOV DL, 0AH  ; 换行
    INT 21H
    POP DX       ; 恢复寄存器
    POP AX
ENDM

; 调用宏
CODE SEGMENT
START:
    PRINT_NEWLINE  ; 直接调用
    ; ...
CODE ENDS
示例 2:带参数宏(加法)
; 定义宏:将两个数相加,结果存入指定寄存器
ADD_NUM MACRO REG, NUM1, NUM2
    MOV REG, NUM1
    ADD REG, NUM2
ENDM

; 调用宏
ADD_NUM AX, 100H, 200H  ; 等价于 MOV AX,100H; ADD AX,200H

3、宏中的局部标号

在 8086 宏汇编中,局部标号是解决宏体内部标号冲突的核心机制 —— 如果宏被多次调用,未声明为局部的标号会因重复定义导致汇编错误,而局部标号仅在当前宏展开实例中有效,不会与其他宏 / 主程序的标号冲突。

3.1、为什么需要局部标号?

假设定义一个累加宏,宏体包含循环标号LOOP1

asm

; 错误示例:无局部标号,多次调用会冲突
ADD_MACRO MACRO NUM
    MOV AX, 0
LOOP1:  ; 全局标号,第二次调用宏时会提示"重复定义LOOP1"
    ADD AX, NUM
    DEC NUM
    JNZ LOOP1
ENDM

; 第一次调用(正常)
ADD_MACRO 5
; 第二次调用(报错:LOOP1已定义)
ADD_MACRO 10

此时必须将LOOP1声明为局部标号,确保每次宏展开时生成唯一的标号。

3.2、局部标号的实现方式(MASM/TASM)

8086 宏汇编中,局部标号主要通过 LOCAL 伪指令实现,语法如下:

1. 核心语法
宏名 MACRO [参数]
    LOCAL 标号1, 标号2, ...  ; 必须放在宏体第一行(宏指令后、其他指令前)
    ; 宏体(可使用局部标号)
ENDM
  • LOCAL 必须是宏体的第一条语句,否则汇编器报错;
  • 可声明多个局部标号,用逗号分隔;
  • 汇编器会自动为每个宏展开实例的局部标号生成唯一名称(如 ??0000??0001),避免冲突。
2. 正确示例(解决上述冲突)
; 正确示例:带局部标号的累加宏
ADD_MACRO MACRO NUM
    LOCAL LOOP1  ; 声明局部标号(必须在宏体第一行)
    MOV AX, 0
LOOP1:  ; 局部标号,每次展开生成唯一名称
    ADD AX, NUM
    DEC NUM
    JNZ LOOP1
ENDM

; 多次调用无冲突
CODE SEGMENT
START:
    ADD_MACRO 5   ; 展开后标号为 ??0000
    ADD_MACRO 10  ; 展开后标号为 ??0001
    MOV AH, 4CH
    INT 21H
CODE ENDS
END START

宏库

8086 CPU 的宏汇编语言程序设计 中,“宏库”(Macro Library)是指一组预先定义好的 宏指令(macro definitions),用于简化编程、提高代码复用性和可读性。这些宏通常封装了常用的代码段,比如输入输出、字符串处理、中断调用等。


一、什么是宏(Macro)?

在汇编语言中, 是一种由程序员定义的“伪指令”,它不是一条 CPU 指令,而是在 汇编阶段 被展开为若干条真实指令的模板。

例如:

; 定义一个宏:显示字符
DISPLAY_CHAR MACRO char
    MOV DL, char
    MOV AH, 02H
    INT 21H
ENDM

使用时:

DISPLAY_CHAR 'A'

汇编器会将其展开为:

MOV DL, 'A'
MOV AH, 02H
INT 21H

二、8086 宏库的常见内容

典型的 8086 宏库可能包含以下功能模块:

功能类别常见宏示例
输入/输出PRINT_STRING, READ_CHAR, PRINT_NUM
数值转换HEX_TO_ASCII, DEC_TO_STR
系统调用封装EXIT_PROGRAM, CLEAR_SCREEN
内存操作MEM_COPY, MEM_FILL
调试辅助DEBUG_MSG, PAUSE

三、如何使用宏库?

  1. 创建宏库文件(如 mylib.mac):

    ; mylib.mac
    PRINT_MSG MACRO msg
        LEA DX, msg
        MOV AH, 09H
        INT 21H
    ENDM
    
    EXIT MACRO
        MOV AH, 4CH
        INT 21H
    ENDM
  2. 在主程序中包含宏库

    INCLUDE mylib.mac
    
    DATA SEGMENT
        MSG DB 'Hello, 8086!$'
    DATA ENDS
    
    CODE SEGMENT
        ASSUME CS:CODE, DS:DATA
    START:
        MOV AX, DATA
        MOV DS, AX
    
        PRINT_MSG MSG
        EXIT
    CODE ENDS
        END START

⚠️ 注意:INCLUDE 是汇编器(如 MASM、TASM)支持的伪指令,用于插入外部文件内容。

posted @ 2025-12-13 16:47  chenlight  阅读(9)  评论(0)    收藏  举报  来源