汇编:宏汇编、宏库

宏定义与宏调用

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

相关推荐
3824278274 小时前
汇编:条件汇编、
前端·汇编·数据库
white-persist4 小时前
【攻防世界】reverse | simple-check-100 详细题解 WP
c语言·开发语言·汇编·数据结构·c++·python·算法
时空自由民.4 小时前
stm32FXX系列MCU汇编启动文件分析
汇编·stm32·单片机
切糕师学AI5 小时前
ARM 汇编指令:STR
汇编·arm开发
3824278276 小时前
IA-32汇编:MOV r/m16,sreg指令、LAHF指令、ALIGN指令、LABEL 指令、TYPEDEF指令解析
汇编
3824278278 小时前
汇编:字符串的输入
汇编
3824278279 小时前
8086 CPU汇编伪操作汇总
汇编
渡我白衣11 小时前
C++可变参数队列与压栈顺序:从模板语法到汇编调用约定的深度解析
c语言·汇编·c++·人工智能·windows·深度学习·硬件架构
旧梦吟1 天前
脚本语言 汇编
汇编