宏的定义和调用

宏的定义

用于重复使用特定代码的时候,一旦宏被定义好了,它就可以在程序中多次被调用。
宏应该有以下三个部分构成:

  1. 头:定义宏的名称,及其参数
  2. 体:当这个宏被调用的时候所需要执行的代码
  3. 尾:用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
最后修改:2022 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏