宏的定义和调用
宏的定义
用于重复使用特定代码的时候,一旦宏被定义好了,它就可以在程序中多次被调用。
宏应该有以下三个部分构成:
- 头:定义宏的名称,及其参数
- 体:当这个宏被调用的时候所需要执行的代码
- 尾:用ENDM标识这个宏结束
一般格式:
宏的名字 MACRO 参数1,参数2,参数3,···,参数n
;宏的代码
ENDM
例1
定义XCHGW宏,将两个字变量相互替换
XCHGW MACRO WRD1,WRD2
PUSH AX
MOV AX,WRD1 ;AX存储WRD1
XCHG AX,WRD2 ;AX(WRD1)和WRD2 值交换
MOV WRD1,AX ;再把AX的值给WRD1
POP AX
ENDM
例2
定义一个NEWLINE宏,移动到新的一行
NEWLINE MACRO
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H
ENDM
宏的调用
XCHGW ArrayW,ArrayW+2 ;调用例1里的宏
;---------------------分割线-----------------
;实际上程序在内部是执行的下面这段代码,相当于ArrayW把宏里的WRD1替换了;ArrayW+2把宏里的WRD2替换了
PUSH AX
MOV AX,ArrayW
XCHG AX,ArrayW+2
MOV ArrayW,AX
POP AX
宏指令中的LOCAL
如果在宏指令中需要定义变量或标号,当这个宏指令被多次调用的时候,宏就会产生多个相同的变量或标号名,这个时候就会出错。所以当你需要在宏里定义变量或标号的时候,就在MACRO后的下一行写上LOCAL伪指令
一般格式
LOCAL 形式变量1,形式变量2,···
例4
宏BIG_ARRAY:找出字数组元素中最大的元素值存储到AX里
BIG_ARRAY MACRO ARRAY,N
LOCAL @TOP,@NEXT
PUSH BX
PUSH CX
LEA BX,ARRAY
MOV AX,[BX]
MOV CX,N
DEC CX
@TOP:
ADD BX,2
CMP [BX],AX
JLE @NEXT
MOV AX,[BX]
@NEXT:
LOOP @TOP
POP CX
POP BX
ENDM
例5
使用NEWLINE宏编写一个程序,该程序需要3个字符,并按如下所示输出它们。
.MODEL SMALL
.STACK 100H
NEWLINE MACRO
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
ENDM
.CODE
MAIN PROC
MOV AH,2
MOV DL,'?'
INT 21H ;输出问号
MOV AH,1
INT 21H ;键盘输入
MOV BL,AL ;输入的存到BL里
INT 21H ;键盘输入
MOV BH,AL ;输入的存到BH里
INT 21H ;键盘输入
MOV CL,AL ;输入的存到CL里
NEWLINE ;调用宏,换行
MOV DL,BL ;BL存到DL待输出
INT 21H ;输出
NEWLINE ;调用宏,输出
MOV DL,BH ;BH存到DL待输出
INT 21H ;输出
NEWLINE ;调用宏,输出
MOV DL,CL ;CL存到DL待输出
INT 21H ;输出
MOV AH,4CH ;结束
INT 21H
MAIN ENDP
END MAIN
重复汇编REPT
在编写源程序时,有时会出现连续相同或几乎完全相同的一组代码,这个时候就可以试一重复伪指令来重复汇编,从而达到简化程序的目的。
一般格式
REPT 表达式
重复语句
ENDM
指令以REPT开始,ENDM结束。
例6
-定义连续输出N个字符的OUT_CHAR宏,依次输出26个大写、26个小写字母和10个数字,如下所示:
.MODEL SMALL
.STACK 100H
NEWLINE MACRO ;定义输出回车的宏
MOV AH,2
MOV DL,0DH
INT 21H
MOV DL,0AH
INT 21H ;输出回车
ENDM
OUT_CHAR MACRO BYT,N ;定义输出字母的宏N代表重复的次数
MOV AH,2
MOV DL,BYT
REPT N
INT 21H
INC DL ;加一
ENDM
ENDM
.CODE
MAIN PROC
OUT_CHAR 'A',26 ;输出大写的二十六个字母
NEWLINE ;回车
OUT_CHAR 'a',26 ;输出小写的二十六个字母
NEWLINE ;回车
OUT_CHAR '0',10 ;输出0-9
MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
重复汇编IRP
伪指令IRP的作用是用每个参数创建一组语句,其重复次数由伪指令后面参数表中参数的个数来确定。
一般格式:
IRP 形式参数,<实参1, 实参2, ……, 实参n>
重复的语句
ENDM
例7
使用IRP定义宏SAVE_DATA和RESTORE_DATA,在堆栈中存储寄存器或字变量
SAVE_DATA MACRO DATA
IRP D,<DATA>
PUSH D
ENDM
ENDM
RESTORE_DATA MACRO DATA
IRP D,<DATA>
POP D
ENDM
ENDM
SAVE_DATA <AX,BX,SI,WRD1>
PUSH AX
PUSH BX
PUSH SI
PUSH WRD1
RESTORE_DATA <WRD1,SI,BX,AX>
POP WRD1
POP SI
POP BX
POP AX