与高级语言相比,汇编语言有一个显著的特点就是源程序比较冗长。举一个简单的例子,如果需要将字符串"Best wish to you"显示在屏幕上,应该如何编写程序呢?
没有比这再简单的了,请看下面这个"BESTWISH"程序:
code segment assume cs:code,ds:code org 100h main proc near mov dx,offset msg mov ah,09 int 21h ret msg db 'Best wish to you',0dh,0ah,24h main endp code ends end main
问题的确不难,但这个程序确不是很简单,整整四条指令还有不少伪指令,要知道如果用BASIC语言编写同样功能的程序只要一条语句:
PRINT "Best wish to you"。
单单显示一个字符串还说明不了这里面有什么复杂性,但是请注意,编写一些比较大的程序时往往要显示很多个字符串,如果每显示一次字符串都这样编写程序可就有些繁人了。有没有什么比较简单的处理方法呢?比如说把这一组指令用一个单词代替可不可以呢?
这完全可以。我们所使用的汇编语言编译系统,无论是MASM还是TASM,都支持 "宏汇编"功能。"宏"的概念比较抽象,在汇编语言中所谓"宏"指得就是由一组指令构成的具有某种功能的程序块。
如果从定义上理解, "宏"好象就是子程序,实际并非如此,"宏"与子程序有着很大的不同之处。在具体讨论这个问题之前,我们先来研究下面给出的这个程序:
print MACRO ;定义一个"宏" mov ah,09 ;选择DOS的09H功能 int 21h ;输出DX寄存器指向的字符串 ENDM ;"宏"定义结束 code segment assume cs:code,ds:code org 100h main proc near mov dx,offset msg ;DX寄存器指向字符串MSG print ;利用"宏"输出字符串 ret ;结束进程 msg db 'Best wish to you',0dh,0ah,24h main endp code ends end main
注意在指令"MOV"与"RET"之间多出了一个"PRINT",这个"PRINT"是什么含义呢?本来将字符串的首地址送入DX寄存器之后应该调用21H中断的09H功能,中断调用的指令又跑到哪儿去了呢?
实际上"PRINT"的作用就是调用21H中断的09功能,这个"PRINT"并非是什么伪指令之类的东西,它就包含在源程序之中。请看源程序最前面的四行:
print MACRO mov ah,09 int 21h ENDM
"PRINT"实际上是"MOV AH,09"与"INT 21H"这两条指令的"替身",这五个字母就相当于两条指令。这种代替关系就是通过"宏"产生的。源程序中有两个大写的伪指令--"MACRO"与"ENDM",这两个伪指令之间包含着一些代码,这组代码就是所谓的"具有一定功能的程序块"。比如我们给出的这个例子所具有的功能就是调用21H中断的09功能。象这样由伪指令"MACRO"与"ENDM"包含的程序段就是一个"宏"。