1、7.1 宏汇编宏汇编 在汇编语言中,如果在源程序中多次使用在汇编语言中,如果在源程序中多次使用到同一个程序段,则可以将这个程序段定到同一个程序段,则可以将这个程序段定义成一个义成一个“指令指令”,叫,叫宏指令。宏指令。w 仅是仅是源程序级的简化源程序级的简化:宏:宏调用调用在汇编时在汇编时进行程序语进行程序语句的展开,不需要返回;句的展开,不需要返回;不减小目标程序,执行速不减小目标程序,执行速度没有改变度没有改变w 通过形参、实参结合实现通过形参、实参结合实现参数传递,简捷直观、灵参数传递,简捷直观、灵活多变活多变w 还是还是目标程序级的简化目标程序级的简化:子程序调用子程序调用在执行时在执
2、行时由由CALLCALL指令转向、指令转向、RETRET指令返指令返回;形成的目标代码较短,回;形成的目标代码较短,执行速度减慢执行速度减慢w 需要利用寄存器、存储单需要利用寄存器、存储单元或堆栈等传递参数元或堆栈等传递参数比较比较宏宏子程序子程序共同点:共同点:简化源程序的书写;节省编程的工作量简化源程序的书写;节省编程的工作量w 宏与子程序具有各自的特点,程序员应宏与子程序具有各自的特点,程序员应该根据具体问题选择使用那种方法该根据具体问题选择使用那种方法w 通常,当程序段较短或要求较快执行时,通常,当程序段较短或要求较快执行时,应选用宏;当程序段较长或为减小目标应选用宏;当程序段较长或为
3、减小目标代码时,要选用子程序代码时,要选用子程序比较比较宏宏子程序子程序7.1 宏汇编宏汇编宏:宏:具有宏名的一段汇编语句序列具有宏名的一段汇编语句序列宏定义宏定义时书写时书写宏指令:宏指令:这段汇编语句序列的缩写这段汇编语句序列的缩写宏调用宏调用时书写时书写宏展开:宏展开:宏指令处用这段宏代替的过程宏指令处用这段宏代替的过程宏汇编宏汇编时实现时实现宏的参数宏的参数功能强大,颇具特色功能强大,颇具特色配合宏,还有配合宏,还有宏操作符宏操作符和有关伪指令和有关伪指令一、宏定义宏定义mainbeginmainbegin MACROMACRO ;定义名为定义名为mainbeginmainbegin的
4、宏,无参数的宏,无参数mov ax,datamov ax,data;宏定义体宏定义体mov ds,axmov ds,axENDMENDM;宏定义结束宏定义结束宏名宏名 macro macro 形参表形参表 宏定义体宏定义体endmendmmainendmainendMACRO retnumMACRO retnum;带有形参带有形参retnumretnummov al,0mov al,0mov ah,retnum mov ah,retnum;宏定义中使用参数宏定义中使用参数int 21hint 21hENDMENDM宏注释符宏注释符宏调用及其展开宏调用及其展开start:start:mainbe
5、ginmainbegin;宏调用,建立宏调用,建立DSDS内容内容mainend 4chmainend 4ch ;宏调用,返回宏调用,返回DOSDOSend startend start宏名宏名 实参表实参表 w 宏调用的实质是在汇编过程中进行宏展开宏调用的实质是在汇编过程中进行宏展开w 对于宏来说,对于宏来说,先定义,后调用。先定义,后调用。w 宏展开的具体过程是:当汇编程序扫描源程序遇宏展开的具体过程是:当汇编程序扫描源程序遇到已有定义的宏调用时,即用相应的宏定义体取代到已有定义的宏调用时,即用相应的宏定义体取代源程序的宏指令,同时用位置匹配的实参对形参进源程序的宏指令,同时用位置匹配的实
6、参对形参进行取代行取代宏展开宏展开start:start:mainbeginmainbegin;宏指令宏指令 1 1mov ax,datamov ax,data;宏展开宏展开 1 1mov ds,axmov ds,axmainendmainend 4ch4ch;宏指令宏指令 1 1mov al,0mov al,0;宏展开宏展开 1 1mov ah,4chmov ah,4ch 1 1int 21hint 21h在汇编时,用宏定义体的代码在汇编时,用宏定义体的代码序列替代宏指令的过程序列替代宏指令的过程 宏展开 当宏汇编程序扫描到宏指令语句当宏汇编程序扫描到宏指令语句(即宏即宏调用调用)时,宏汇编
7、程序就把宏指令定义中宏时,宏汇编程序就把宏指令定义中宏体的程序段代码替代宏指令语句。体的程序段代码替代宏指令语句。若是带参数的宏调用,则同时用相应的若是带参数的宏调用,则同时用相应的实参替代宏体中对应形参的位置,并对原有实参替代宏体中对应形参的位置,并对原有宏体代码作修改。宏体代码作修改。宏展开 下面是一个源程序的列表文件,它展示了宏下面是一个源程序的列表文件,它展示了宏定义、宏调用和宏展开的全部过程。定义、宏调用和宏展开的全部过程。在列表文件中,左边带在列表文件中,左边带“+”号的指令是宏号的指令是宏汇编程序在宏展开时自动生成的指令。汇编程序在宏展开时自动生成的指令。宏定义本身不生成任何目标
8、代码,宏指令宏定义本身不生成任何目标代码,宏指令语句本身也不生成目标代码,它仅表示宏调用语句本身也不生成目标代码,它仅表示宏调用出现的位置。出现的位置。EXCH_MEMEXCH_MEMMACRO MACRO MEM_lMEM_l,MEM_2MEM_2,REGREG MOV MOV REGREG,MEM_1MEM_1XCHG XCHG REGREG,MEM_2MEM_2MOV MOV MEM_1MEM_1,REGREGENDMENDMDATADATA SEGMENTSEGMENT DA_W1 DW 55AAHDA_W1 DW 55AAH DA_W2 DA_W2 DW 6688HDW 6688H
9、DATA DATA ENDSENDSCODE SECMENTCODE SECMENTASSUME CSASSUME CS:CODECODE,DSDS:DATADATA,SSSS:STACKSTACKSTARTSTART:MOVMOVAXAX,DATADATA MOV MOV DSDS,AXAX ;宏调用和宏展开宏调用和宏展开 EXCH_MEM DA_W1,DA_W2,AX ;宏指令语句宏指令语句 +MOV AX,DA_Wl +XCHG AX,DA_W2 +MOV DA_W1,AX MOV AH,4CHINT 21HCODE ENDS END START子程序调用和宏调用的区别子程序调用和宏调用
10、的区别 子程序时在程序执行期间由主程序调子程序时在程序执行期间由主程序调用的,它只占有它自身大小的一个空间用的,它只占有它自身大小的一个空间 宏调用是在汇编期间展开的,每调用宏调用是在汇编期间展开的,每调用一次就把宏定义体展开一次,因而它占有一次就把宏定义体展开一次,因而它占有的存储空间与调用次数有关。的存储空间与调用次数有关。w 可以可以无参数无参数,例如,例如mainbeginw 可以带有可以带有一个参数一个参数,例如,例如mainendw 也可以具有也可以具有多个参数多个参数;w 参数可以是参数可以是常数、变量、存储单元、指令常数、变量、存储单元、指令(操作码)或它们的一部分(操作码)或
11、它们的一部分,也可以是,也可以是表达表达式式;w 宏定义体可以是任何合法的汇编语句,既可宏定义体可以是任何合法的汇编语句,既可以是以是硬指令序列硬指令序列,又可以是,又可以是伪指令序列伪指令序列;宏定义;宏定义shlextshlextmacro shloprand,shlnummacro shloprand,shlnumpush cxpush cxmov cl,shlnummov cl,shlnumshl shloprand,clshl shloprand,clpop cxpop cxendmendm;宏指令宏指令shlext ax,6shlext ax,6;宏展开宏展开 1 1push cx
12、push cx 1 1mov cl,06mov cl,06 1 1shl ax,clshl ax,cl 1 1pop cxpop cx 为了宏定义和引用的某些特殊需要,有时为了宏定义和引用的某些特殊需要,有时实参是由字符、空格等特殊符号组成的,因此实参是由字符、空格等特殊符号组成的,因此汇编程序支持几个具有特定含义的运算符。汇编程序支持几个具有特定含义的运算符。1 1连接运算符连接运算符&在宏定义中,如果形式参数与其它字符连接在一在宏定义中,如果形式参数与其它字符连接在一起,或形式参数出现在字符串之中,那么,就起,或形式参数出现在字符串之中,那么,就必须使用连接运算符必须使用连接运算符(&)。
13、在宏指令定义的具体。在宏指令定义的具体使用时,连接操作符使用时,连接操作符&可以在形参的前面,也可以在形参的前面,也可在形参的后面。在宏指令展开时,对应形参可在形参的后面。在宏指令展开时,对应形参的实参就与它前面或后面的符号连接在一起构的实参就与它前面或后面的符号连接在一起构成一个新的符号。成一个新的符号。;宏定义;宏定义LEAP MACRO COND,LAB J&COND LABENDM;宏调用LEAP Z,THERELEAP NZ,HERE;宏展开JZ THEREJNZ HERE2.2.文本操作符文本操作符 文本操作符是一对尖括号文本操作符是一对尖括号,用它括起来的内容,用它括起来的内容将
14、作为一个字符串来进行形式参数的整体替换。将作为一个字符串来进行形式参数的整体替换。在宏引用时,在宏引用时,如果实参内包含逗号、空格等如果实参内包含逗号、空格等间隔符,则必须使用该操作符,间隔符,则必须使用该操作符,以保证实参的完以保证实参的完整性。如果实参是某个具有特殊含义的字符,为整性。如果实参是某个具有特殊含义的字符,为了使它只表示该字符本身,也需要用该运算符括了使它只表示该字符本身,也需要用该运算符括起来。起来。NUMBERMACROTHEDATADBTHEDATAENDM 假设在程序中调用此宏指令:假设在程序中调用此宏指令:DATA SEGMENT NUMBER DATA ENDS 则
15、宏展开为:则宏展开为:DATA SEGMENT DB 1,3,5 DATA ENDS 如果不加如果不加,则在宏展开为:,则在宏展开为:DB 1 ;而而3,5按规则被忽略按规则被忽略3 3 表达式操作符表达式操作符 进行宏调用时,如要在实参中使用进行宏调用时,如要在实参中使用“”,则在宏指令调用时宏汇编程序将,则在宏指令调用时宏汇编程序将获取获取“”后常数表达式的值作为参数,后常数表达式的值作为参数,而非表达式本身。而非表达式本身。NUMBER MACRO X,Y,Z,DB X,Y,Z ENDM若宏调用为:若宏调用为:I EQU 10 J EQU 50 NUMBER 16,I+J,J-I 则相应
16、的宏展开为:则相应的宏展开为:DB 16,60,404 4字符操作符字符操作符!字符操作符字符操作符!的使用表明,的使用表明,“!”后的字符后的字符不是特殊字符,而是普通字符。这样对于不是特殊字符,而是普通字符。这样对于包含在包含在“”、“!”、“%”之之间的文本串,汇编程序将能以普通字符处间的文本串,汇编程序将能以普通字符处理。如将理。如将“!”作为普通字符,则使作为普通字符,则使用!。用!。例如宏指令定义:例如宏指令定义:DEFIN_ST MACRO STRING DB&String&S ENDM 则宏调用:则宏调用:DEFIN_ST 0):):$其宏展开为:其宏展开为:DB Please
17、 Input a Integer(0):):$宏嵌套宏嵌套 宏指令定义中还含有宏定义或者是宏指令的定义中含有宏调用,这两种情况都称为宏嵌套宏嵌套。1.1.宏定义中嵌套宏定义宏定义中嵌套宏定义 ABCD_1MACRO ABCD_2MACRO ENDM ENDM宏指令定义中嵌套宏定义实例宏指令定义中嵌套宏定义实例 INIT_1MACRO X,Y,Z SHIFT_&Y MACRO MOV CL,X S&Z Y,CL ENDM ENDM 如采用下面的宏调用:INIT_1 2,BX,AR ;即将BX算术右移2位的宏指令 则相应的宏展开为:SHIFT_BX MACRO MOV CL,2 SAR BX,CL
18、 ENDM宏嵌套宏嵌套 2 在宏定义中嵌套宏调用在宏定义中嵌套宏调用 在宏定义中嵌套宏调用的基本形式为:这在宏定义中嵌套宏调用的基本形式为:这种嵌套形式比较简单,只需在宏定义中种嵌套形式比较简单,只需在宏定义中(像在程序中一样像在程序中一样)写出宏指令即可。但必写出宏指令即可。但必须先定义,后调用。须先定义,后调用。宏嵌套宏嵌套ABCD_lMACRO ;定义一个宏定义一个宏 ENDM ABCD_2MACRO ABCD_l ;在宏定义中调用宏在宏定义中调用宏 ENDM局部标号伪指令局部标号伪指令LOCAL 标号列表标号列表宏定义体采用了标号,应使用宏定义体采用了标号,应使用LOCAL加以说明加以
19、说明它必须是宏定义它必须是宏定义MACRO语句之后的第一条语句语句之后的第一条语句与宏有关的伪指令与宏有关的伪指令与宏有关的伪指令与宏有关的伪指令-LOCAL 标号列表标号列表 某些宏定义中存在变量或标号,这些宏定义某些宏定义中存在变量或标号,这些宏定义在同一程序中被多次调用且展开后,就会出现变在同一程序中被多次调用且展开后,就会出现变量或标号重复定义的错误。量或标号重复定义的错误。LOCAL伪指令的使用可以避免此类错误。伪指令的使用可以避免此类错误。在宏展开时,让宏汇编程序自动为其后的形参顺在宏展开时,让宏汇编程序自动为其后的形参顺序生成特殊符号序生成特殊符号 (范围为范围为?0000?FF
20、FFH),并用这些特殊符号来取代宏体中的形参,避免了并用这些特殊符号来取代宏体中的形参,避免了符号重复定义的错误。符号重复定义的错误。格式:格式:LOCAL 形参形参1,形参,形参2;宏定义;宏定义AbsolAbsolmacro oprdmacro oprdlocal nextlocal nextcmp oprd,0cmp oprd,0jge nextjge nextneg oprdneg oprdnext:next:endmendm;宏调用;宏调用absol word ptr bxabsol word ptr bxabsol bxabsol bx;宏展开宏展开 1 1cmp word ptr
21、 bx,0cmp word ptr bx,0 1 1jge?0000jge?0000 1 1neg word ptr bxneg word ptr bx 1 1?0000:?0000:1 1cmp bx,0cmp bx,0 1 1jge?0001jge?0001 1 1neg bxneg bx 1 1?0001:?0001:与宏有关的伪指令与宏有关的伪指令宏定义删除伪指令宏定义删除伪指令PURGE 宏名表宏名表不需要某个宏定义时,可以把它删除不需要某个宏定义时,可以把它删除 格式:格式:PURGE PURGE 宏指令名宏指令名1 1,宏指令名,宏指令名22 取消宏定义的含义是使该宏定义成为空,
22、取消宏定义的含义是使该宏定义成为空,程序中如果出现一个已被取消宏定义的宏调程序中如果出现一个已被取消宏定义的宏调 用,则汇编程序将不会指示出错,但它将忽略用,则汇编程序将不会指示出错,但它将忽略该宏调用,当然也不会予以展开。该宏调用,当然也不会予以展开。与宏有关的伪指令与宏有关的伪指令 宏定义退出伪指令宏定义退出伪指令EXITM伪指令伪指令EXITM表示结束当前宏调用的展开表示结束当前宏调用的展开宏库的建立和调用宏库的建立和调用 有些宏指令在应用过程中效果较好,因此在以后的有些宏指令在应用过程中效果较好,因此在以后的汇编语言编程时就不必每次在源程序中重复编制一个宏汇编语言编程时就不必每次在源程
23、序中重复编制一个宏指令定义,这样也可减少重复编写时的错误,可以把几指令定义,这样也可减少重复编写时的错误,可以把几个宏定义组成一个宏库,以文件形式供其它源程序调用。个宏定义组成一个宏库,以文件形式供其它源程序调用。当需要宏库文件中的宏定义时,可在新编制的源程当需要宏库文件中的宏定义时,可在新编制的源程序中使用序中使用INCLUDE伪指令。宏汇编程序在汇编源程序伪指令。宏汇编程序在汇编源程序时,如果遇到时,如果遇到INCLUDE伪指令时,就把这伪指令的宏伪指令时,就把这伪指令的宏库文件扫描一遍,如同在这个程序中自己定义的宏一样,库文件扫描一遍,如同在这个程序中自己定义的宏一样,在后面的程序中就可
24、以对宏库中的宏定义直接进行宏调在后面的程序中就可以对宏库中的宏定义直接进行宏调用。用。二、重复汇编二、重复汇编w 重复汇编重复汇编指在汇编过程中,重复展开一段(基本)指在汇编过程中,重复展开一段(基本)相同的语句相同的语句w 重复汇编没有名字,不能被调用重复汇编没有名字,不能被调用w 重复汇编常用在宏定义体中,也可以在一般汇编重复汇编常用在宏定义体中,也可以在一般汇编语句中使用语句中使用w 重复汇编伪指令有三个:重复汇编伪指令有三个:REPEAT按参数值重复按参数值重复FOR按参数个数重复按参数个数重复FORC按参数的字符个数重复按参数的字符个数重复w 最后,用最后,用ENDM结束结束REPE
25、ATREPEAT 重复次数重复次数 重复体重复体ENDMENDMchar=Achar=AREPEAT 26REPEAT 26 db char db char char=char+1 char=char+1ENDMENDM 1 1db chardb char;等效于等效于db Adb A 1 1char=char+1char=char+1 1 1db chardb char;等效于等效于db Bdb B 1 1char=char+1char=char+1.1 1db chardb char;等效于等效于db Zdb Z 1 1char=char+1char=char+1FORFOR 形参形参,实
26、参表实参表 重复体重复体ENDMENDMFOR regad,FOR regad,push regad push regadENDMENDM 1 1push axpush ax 1 1push bxpush bx 1 1push cxpush cx 1 1push dxpush dxFORFOR 形参形参,字符串字符串 重复体重复体ENDMENDMFOR regad,dcbaFOR regad,dcba pop®ad&x pop®ad&xENDMENDM 1 1pop dxpop dx 1 1pop cxpop cx 1 1pop bxpop bx 1 1pop axpop ax不定
27、重复伪操作IRPIRP伪操作伪操作 格式:格式:IRP 形参,重复语句序列 ENDM 每次重复汇编语句序列时,就用一个实参替代形参。每次重复汇编语句序列时,就用一个实参替代形参。第一次用第一个实参替代形参,第二次用第二个实参替第一次用第一个实参替代形参,第二次用第二个实参替代形参,直到所有实参用完为止。重复汇编次数由尖括代形参,直到所有实参用完为止。重复汇编次数由尖括号括起来的实参个数所决定。注意实参必须用尖括号括号括起来的实参个数所决定。注意实参必须用尖括号括起来,各个实参之间用逗号分开,如果实参为空,汇编起来,各个实参之间用逗号分开,如果实参为空,汇编程序则约定跳过程序则约定跳过IRPIR
28、P与与ENDMENDM之间的语句,之间的语句,IRPIRP伪指令的形伪指令的形参只能有一个。参只能有一个。不定重复伪操作IRP重复汇编结构举例重复汇编结构举例 IRP REG,PUSH REG ENDM 经汇编展开后为:经汇编展开后为:PUSH AX PUSH BX PUSH CX PUSH DX 不定重复伪操作IRPC伪指令伪指令指令格式:IRPC 形参,重复语句序列 ENDM 每当汇编重复语句序列时,汇编程序将依次用字符串中的一个字符替代形参,直到字符串中的字符替代完毕。重复次数由字符串中字符个数来确定。IRPC和和IRP类似,但自变量表必须是字符串类似,但自变量表必须是字符串三、条件汇编
29、三、条件汇编w 条件汇编伪指令在汇编过程中,根据条件条件汇编伪指令在汇编过程中,根据条件决定汇编的语句决定汇编的语句IFxx 表达式表达式;满足,汇编分支语句体满足,汇编分支语句体1分支语句体分支语句体1 ELSE;不满足,汇编分支语句体不满足,汇编分支语句体2分支语句体分支语句体2 ENDIF;条件汇编结束条件汇编结束条件汇编伪指令条件汇编伪指令伪指令伪指令汇编条件汇编条件IF 1IF 1在第一遍扫描时,扫视条件语句块在第一遍扫描时,扫视条件语句块IF 2IF 2在第二遍扫描时,扫视条件语句块在第二遍扫描时,扫视条件语句块IF IF 表达式表达式表达式表达式0 0IFE IFE 表达式表达式表达式表达式=0=0IFDEF IFDEF 符号符号符号已定义或已被说明为符号已定义或已被说明为EXTRNEXTRNIFNDEF IFNDEF 符号符号符号未定义且也未被说明为符号未定义且也未被说明为EXTRNEXTRNIFB IFB 变量变量变量是空格变量是空格IFNB IFNB 变量变量变量不是空格变量不是空格IFIDN IFIDN 变量变量1,1,变量变量2 2变量变量1 1和变量和变量2 2的字符串相同的字符串相同IFNIDN IFNIDN 变量变量1,1,变量变量2 2变量变量1 1和变量和变量2 2的字符串不相同的字符串不相同