汇编学习笔记45

三、宏指令的使用

3.宏调用的参数个数可以与定义时不一致。

宏调用时使用的实参个数应该与宏定义时形参个数一致。但汇编程序并不要求它们必须一致。

若实参个数多于形参个数,则多余的实参被忽略

若实参个数少于形参个数,则多余的形参用 空 来代替。

4.特殊的宏运算符

(1) 强迫替换运算符 &

在宏定义中,若参数在其它字符的紧前或紧后,或者参数出现在带引号的字符串中时,就必须使用该运算符,以区分参数

例:

下面定义的宏指令JUMP中,参数CON作为操作码的一部分

JUMP MACRO CON, LIB

J&CON LAB

ENDM

调用宏JUMP及其扩展如下:

JUMP NZ HERE

+ JNZ HERE

JUMP Z THERE

+ JZ THERE

例2:

下而定义的宏MSGGEN中,两个参数合并成标号,一个参数用在字符串中

MSGGEN MACRO LAB, NUM, XYZ

LAB&NUM DB 'HELLO MR&XYZ', 0DH, 0AH, 24H

ENDM

调用宏MSGGEN及其宏扩展如下:

MSGGEN MSG, 1, TAYLOR

+ MSG1 DB 'HELLO MRTAYLOR', 0DH, 0AH, 24H

(2) 字符串读运算符 <>

在宏调用,重复块和条件汇编中,由它括起的内容作为一个字符串。

在宏调用时,若实参包含逗号,空格等间隔符,则必须使用读运算符,以保证实参的完整。

若实参是某个有特殊意义的字符,为了使它只表示字符本身,也要使用该运算符把它括起来。

例:

定义如下宏

DFMESS MACRO MESS

DB '&MESS', 0DH, 0AH, 0

ENDM

调用及其扩展如下:

DFMESS <THIS IS A EXAMPLE>

+ DB 'THIS IS A EXAMPLE', 0DH, 0AH, 0

DFMESS THIS IS A EXAMPLE

+ DB 'THIS', 0DH, 0AH, 0

(3) 文字字符运算符  !

该运算符使用其后的一个字符只作为一般字符。

在宏调用时,如果实参中含有一些特殊字符,为了使这些特殊字符作为一般字符来处理,那么就必须在其前使用该运算符。

例: 调用上例DFMESS

DFMESS <CAN NOT CMTC !> 09>

+ DFMESS 'CAN NOT CMTC > 09', 0DH, 0AH, 0

DFMESS <CAN NOT CMTC > 09>

+ DFMESS 'CAN NOT CMTC ', 0DH, 0AH, 0

(4) 表达式运算符 %

在宏调用时,使用该运算符把其后表达式结果作为实参替换,而非表达式本身

例: 调用上例DFMESS

DFMESS %(12+3-4)

+ DB '11', 0DH, 0AH, 0

DFMESS 12+3-4

+ DB '12+3-4', 0DH, 0AH, 0

(5) 宏注释 ;;

在宏定义中,如果注释以两个分号引导,那么宏展开时,该注释不出现。

5. 宏与子程序的区别

(1) 宏调用是通过宏指令名进行的,在汇编时,由汇编程序把宏展开, 有多少次宏调用,就有多少次宏展开。因此并不简化子程序。

子程序调用是在执行期执行CALL指令进行的,子程序代码只在目标程序中出现一次,所以目标程序也得到相应的优化。

(2) 宏调用时参数由汇编程序通过实参替换的方式传递,所以参数很灵活。

子程序调用时参数通过寄存器,堆栈或约定存储单元传递。

(3) 宏调用时在汇编时完成的,所以不需要额外的时间开销。

子程序调用和子程序返回均需要时间,而且还涉及堆栈。

 

posted @ 2011-01-21 20:04  杨海龙  阅读(268)  评论(0编辑  收藏  举报