汇编语言——宏
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ENDM
汇编语言规定,字符串中的形参必须用分隔符“&”从其它 部分分离出来。对于下面两个宏调用,
msg 1,John
msg 2,Henrry 宏展开的结果是:
+ var1 DB + var2 DB
'HELLO, John' 'HELLO, Henrry'
*7.3.4 宏操作中形参与实参的对应关系
由于宏是伪操作,形参与实参的对应方法是由汇编程序 决定的,与高级语言中形参与实参的对应方式有很大的不同。 汇编语言规定:
宏体
ENDM
形式参数可以出现在宏体中的任何位置,可以在操作数 中,可以在指令助记符的位置,甚至还可以是其中的一部分。 下面的几个例子用来说明参数的各种不同用法。
【例7.11】普通用法,形式参数出现在操作数的位置。
dch MACRO x
MOV AH,2
MOV DL,x
INT 21H
ENDM
源程序中调用宏dch时,应该在宏名字的后面跟一个实际 参数,从例7.11的宏体可以看出,这个实际参数应该是用于屏 幕显示的一个ASCII字符。因而,源程序中用下面的写法连续 两次调用上述宏,就可以实现回车换行操作。宏展开时,对每 一次宏调用,将分别以相应的实际参数代换宏体中的形式参数。
【例7.10】参照汇编程序的处理方法,对下面程序中的宏进 行展开。
back =
4CH
dosint EQU 21H
dispch MACRO
MOV AH,2
MOV DL, '* '
INT 21H
ENDM
code SEGMENT
ASSUME CS:code
main: dispch
dispch
MOV
AH,back
对例7.12后面的3个调用,调用例7.13中的宏可以达到同 样的效果,相应写法是:
cc1 G,n1
cc1 BE,n2
cc1 NZ,n3
【例7.14】形式参数还可以出现在变量定义伪操作的初值表 中,甚至是以字符串形式出现的初值。
msg
MACRO num,pname
var&num DB
'HELLO, &pname'
INT
dosint
code ENDS
END
main
【解】宏展开后的结果是:
+ MOV
AH,2
+ MOV
DL, '*'
+ INT
21H
+ MOV
AH,2
+ MOV
DL, '*'
+ INT
21H
MOV
AH,4CH
INT
21H
由于宏展开是汇编程序翻译的一个步骤,宏展后的结果 并不是源程序,所以展开后不再写出完整的程序格式,只列 出有效指令部分。
(1)“宏名”是一个标识符,一个程序中可以定义多个 宏,对每一个宏必须以不同的标识符命名,且宏名不能与变 量、标号、段名等标识符同名。
(2)汇编语言规定,宏定义的起始标记MACRO前面必须 写宏的名字,而结束标记ENDM的前面却不允许写任何内容, 写在起止标记之间的部分称为宏体,宏体部分通常定义仅仅用来告诉汇编程序,将来宏调用时复制 的对象是什么,宏定义中的程序段并不是程序的一部分,也 就是说,如果程序中定义了一个宏而没有调用它,汇编程序 将忽略宏定义。
(4)宏定义可以写在程序的任何地方,但习惯上总是把 宏定义写在程序的最前面。
宏定义与编辑器中的文字块的定义有相似之处,也有一 些差别。两者都需要以特定的方式说明开始和结束的位置。 文字块是文件的一部分,而宏体中的程序段必须经过宏调用 才能复制到源程序中正确的位置,没有被调用的宏体在汇编 程序翻译时会被忽略。
(1)形参表中的多个参数项之间必须用逗号分隔,但实 参表的各个参数项可以用逗号也可以用空格分隔。
7.3.2 宏调用
定义后的宏名又称为宏指令。经宏定义后,就可以在 源程序中调用宏了。宏调用的方式是在源程序中需要复制 宏体的地方写宏的名字。宏名单独占一行,当源程序被汇 编时,汇编程序将对宏调用进行宏体复制,并取代宏名, 这种复制操作称为宏展开。为了与源程序的其它部分相区 别,后面的叙述中,对由宏调用而展开后得到的指令,都 在前面标以加号“+”以示区别。
dch 13
dch 10
【例7.12】形式参数可以出现在助记符的位置。
cc MACRO cmd,lab
CMP AX,BX
cmd
lab
ENDM
上述宏在调用时可以用不同的实际参数代换形式参数 cmd,使得宏体中的第2行是不同的指令。比如下面是几个调 用的例子,请读者自己写出宏展开的结果。
cc JG,n1
7.3.3 带参数的宏
如果宏只能对完全相同的程序段进行复制,那就没有多 大的应用价值了,宏的好处主要体现在每次调用而展开的宏 体可以不同。这需要在宏定义时以形式参数指明宏体中的哪 些部分可以被不同的实际参数代替,每次调用时在宏名字的 后面附带实际参数。完整的宏定义格式是:
宏名 MACRO [形式参数表]
cc JBE,n2
cc JNZ,n3
【例7.13】宏的形式参数可以作为一个标识符的一部分。这 时,必须用符号“&”把形式参数与标识符的其余部分分开。 例7.12中的宏定义还可以写成下面的形式:
cc1 MACRO cmd,lab
CMP
AX,BX
J&cmd lab
ENDM
宏体中第2行的J&cmd就是在一个标识符中(例7.13中表 现为指令助记符)含有形式参数,符号“&”用于把形参cmd 从标识符中分离出来。如果没有分隔符号“&”,汇编程序将 把Jcmd作为一个整体处理,而不知道其中的cmd是形参。
7.3 宏
程序中使用宏分为定义和调用两个部分。宏定义用来说 明哪些指令或伪指令是将在程序中重复出现的程序段;宏调 用是用来告诉汇编程序,在翻译前先把宏定义中的程序段复 制一遍。可见,宏定义和宏调用都是告诉汇编程序如何处理, 属于伪操作。
7.3.1 宏定义
【格式】 宏名 MACRO 宏体
【说明】
ENDM
可以看到,汇编程序对宏调用与已定义的常量及符号的 引用的处理是很类似的,定义部分在汇编处理结束后就已完 成它的作用。汇编程序翻译后得到的机器代码中没有宏、常 量等的定义,只是调用或引用部分被代换成宏体或定义的内 容。宏与常量定义及符号定义的差别在于,常量及符号定义 都必须在一行写完,对常量和符号的引用只能代换指令中的 操作数,或者操作数的一部分,宏调用则可以代换一段程序。 不仅如此,宏还允许代换的内容有个别地方不同,这是通过 带参数的宏实现的。