汇编:宏汇编、宏库

宏定义与宏调用

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

相关推荐
请输入蚊子12 小时前
«操作系统真像还原» 第二章 编写MBR主引导记录
linux·汇编·操作系统·bochs·操作系统真像还原
188号安全攻城狮13 小时前
【PWN】HappyNewYearCTF_8_ret2csu
linux·汇编·安全·网络安全·系统安全
切糕师学AI4 天前
ARM 汇编指令系列文章导读
汇编·arm开发
果粒蹬i4 天前
从割裂到融合:MATLAB与Python混合编程实战指南
开发语言·汇编·python·matlab
AUVpwoxkW6 天前
关键词:混合储能,VMD,麻雀搜索算法,遗传算法,混合储能容量配置优化,混合储能功率分配
汇编
取个名字太难了a6 天前
x64(一)
汇编
xiaobuding_QAQ7 天前
51汇编仿真proteus8.15学习篇四(附源码)
汇编·单片机·学习·proteus
xiaobuding_QAQ7 天前
51汇编仿真proteus8.15学习篇三(附源码)
汇编·单片机·学习·proteus
188号安全攻城狮8 天前
【PWN】HappyNewYearCTF_2_栈上变量覆写1
linux·运维·汇编·安全·网络安全
草莓熊Lotso8 天前
Linux 进程创建与终止全解析:fork 原理 + 退出机制实战
linux·运维·服务器·开发语言·汇编·c++·人工智能