宏定义与宏调用
宏汇编的核心优势是宏(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 |
三、如何使用宏库?
-
创建宏库文件 (如
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 -
在主程序中包含宏库:
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)支持的伪指令,用于插入外部文件内容。