汇编:宏汇编、宏库

宏定义与宏调用

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

相关推荐
水饺编程7 天前
第2章:Linux 基础,解压缩【.tar.bz2】压缩包文件
linux·c语言·汇编
Zevalin爱灰灰7 天前
Linux入门第二部分(ARM裸机篇) 第二章 Cortex-A7 MPCore架构与ARM汇编基础
linux·汇编·arm开发·嵌入式
Zevalin爱灰灰7 天前
Linux入门第二部分(ARM裸机篇) 第三章 汇编LED驱动实验
linux·汇编·arm开发
水饺编程8 天前
第2章:Linux 基础,制作【.tar.xz】压缩包文件
linux·c语言·汇编
小向是个Der10 天前
嵌入式进阶——编译与链接
汇编·单片机·学习·编译原理·交叉编译
二十七日秋10 天前
算法刷题笔记「Day 1|四道 OJ 入门题里的深坑」
c语言·汇编·数据结构·c++·笔记·python·算法
银河麒麟操作系统10 天前
两案例入选全球计算联盟年度产业应用案例汇编
大数据·汇编·人工智能
abc light10 天前
ARM 裸机开发(2)——ARM 汇编与启动代码
汇编·arm开发
soso196811 天前
Modbus协议开发实战指南
汇编
水饺编程12 天前
第2章:Linux 基础,解压缩【.tar.gz】压缩包
linux·c语言·汇编