汇编:宏汇编、宏库

宏定义与宏调用

宏汇编的核心优势是宏(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)支持的伪指令,用于插入外部文件内容。

相关推荐
AC赳赳老秦16 小时前
公开 CSV 数据集批量处理实战:用 OpenClaw 高效完成下载、清洗与标准化分析样本生成
java·开发语言·汇编·c++·python·deepseek·openclaw
斑马1399 天前
ARM学习笔记(二)——ARM汇编基础
汇编·arm开发·arm
wechatbot8889 天前
【极客互动】企业微信Spring Boot 调度 SearchContact开发自动添加外部联系人网关
汇编·微信·自动化·企业微信·rpa
星栖与芯10 天前
LiteOS-M 切换汇编逐行图解(5):HalPendSV 任务切换的现场搬运(五阶段逐行)
汇编·stm32·嵌入式硬件·harmonyos
星栖与芯10 天前
LiteOS-M 切换汇编逐行图解(4):中断三件套与 HalTaskSchedule 触发
汇编·stm32·单片机·嵌入式硬件·harmonyos
xx~t11 天前
嵌入式——ARM——汇编2
linux·汇编·arm开发·嵌入式硬件·启动代码
祖力5511 天前
ARM汇编LED实验
汇编·arm·imx6ull
索端阳12 天前
ARM Day02 学习总结:ARM汇编基础核心知识点梳理
汇编·学习·arm
xx~t12 天前
嵌入式——ARM——汇编1
linux·汇编·arm开发·嵌入式硬件·arm
索端阳13 天前
初识 ARM Cortex-A7,嵌入式底层入门总结
汇编·嵌入式硬件