1、1,第8章 汇编语言高级编程技术,2,7.1 宏 指 令 7.2 宏指令库 7.3 重复伪指令 7.4 条件伪指令,3,7.1 宏 指 令,在高级汇编语言技术中,一段共用语句序列除了可以设计成子程序外,还可以设计成宏指令的形式。宏与子程序类似,首先在源程序中定义一个宏,后面在需要时就可以调用它,并允许传递多个参数。正确灵活使用宏,可以缩短源程序的长度,扩充指令的功能,使源程序更清晰、简洁,有利于阅读、修改与调试,从而提高编程效率。,4,一、宏定义、宏调用、宏扩展,宏指令是源程序中一段有独立功能的程序代码,由用户使用宏定义伪指令定义。 1.宏定义 宏定义伪指令伪指令格式: 宏指令名 MACRO
2、形式参数表 ;宏指令体ENDM宏指令名由用户自起,注意ENDM前没有宏指令名。形式参数表给出了宏定义中所用到的形式参数,形式参数之间用逗号隔开。宏指令体可以由伪指令、指令、甚至于宏指令组成。,5,2.宏调用,宏指令一经定义,就可以在程序中调用它,这被称为宏调用。 宏调用格式:宏指令名 实参数表实参数表给出了宏调用中要用到的实参数,实参数之间用逗号隔开,实参数应和形式参数的顺序、类型一致。,6,3.宏扩展,当源程序被汇编时,汇编程序对每个宏调用进行宏扩展。宏扩展: 宏定义体替换宏指令名 实参数替换形式参数 原则上,实参数个数应和形式参数个数相等,但汇编程序允许它们不等 若实参数个数大于形式参数个
3、数,在替换时多余的实参数不予考虑 若实参数个数小于形式参数个数,则多余的形式参数作为空(字符)或零(数字)处理 应保证用实参数替换形式参数后,所展开的是有效的汇编语句,否则汇编程序会提示错误。,7,例1输入一个字符的宏定义、宏调用、宏扩展,;宏定义 INCHAR MACROMOV AH,1INT 21H ;输入的字符在ALENDM ;宏调用INCHAR ;宏调用 当汇编程序汇编到宏指令INCHAR时对其扩展为:1 MOV AH,11 INT 21H,8,由于宏调用是在宏扩展时替换,一条宏指令在程序中被调用几次,经汇编后其源代码就会在程序中出现几次,而不是像子程序调用那样把控制转移到子程序、执行
4、完后再返回。因此使用宏指令仅仅是减轻了程序设计人员的劳动量,并不能缩短目标码的长度。,9,二、设计宏指令时应注意的问题,宏指令也像子程序那样可以被多次调用或被多个程序共享,设计时需注意: 1宏指令说明在宏指令开头说明功能、调用参数和返回参数。在设计宏指令库时尤其要注意。 2寄存器保存与恢复在宏指令开头及结束处保存和恢复将要用到的寄存器内容,使用PUSH保存、POP恢复。 3说明局部符号若宏指令中包含标号或变量名则一定要用LOCAL伪指令说明,否则当一个程序多次调用该宏指令时会出现符号重复定义错误。,10,三、LOCAL伪指令,格式:LOCAL 局部符号表功能:对局部符号表中的每个符号,在汇编时
5、每扩展一次便建立一个惟一的符号,形如?xxxx。以保证汇编时生成名字的惟一性。说明:xxxx的值在0000FFFF之间。注意:LOCAL伪指令一定要是宏体中的第一个语句,即它应紧跟在宏定义的MACRO之后,中间不能插有任何其它语句(含注释语句)。,11,例2定义一个延时10ms宏指令delay,并且在程序中调用实现延时20ms功能。,;宏定义 DELAY MACROLOCAL LOPMOV CX,2801 LOP: LOOP LOPENDM ;宏调用:DELAYDELAY ;宏扩展:DELAY 0009 B9 0AF1 1 MOV CX,2801 000C E2 FE 1 ?0000: LOO
6、P ?0000 DELAY 000E B9 0AF1 1 MOV CX,2801 0011 E2 FE 1 ?0001: LOOP ?0001,12,四、宏指令中参数的使用,形式参数使宏更通用更灵活,而在宏调用时给出实参数即可。宏指令的实参数可以是常数、寄存器、变量、表达式、操作码或操作码的一部分、指令或伪指令助记符等,如此多的参数种类以及参数传递的方便性是子程序所不能比拟的。宏指令允许嵌套。,13,例3定义在两个字型内存变量之间传送数据的宏指令,并调用之。,MOVE MACRO X,Y ;XYPUSH AXMOV AX,XMOV Y,AXPOP AXENDM DATA SEGMENT VAR
7、1 DW 6543H VAR2 DW ? DATA ENDSMOVE VAR1,VAR2 ;宏调用 ;宏扩展1 PUSH AX 1 MOV AX,VAR11 MOV VAR2,AX1 POP AX,14,例4用宏指令实现清屏、设置光标、显示彩色字符及彩色字符串功能。,;功能:保存寄存器DX、CX、BX、AXPUSHREG MACROPUSH DXPUSH CXPUSH BXPUSH AXENDM ;功能:恢复寄存器AX、BX、CX、DX POPREG MACROPOP AXPOP BXPOP CXPOP DXENDM,15,;功能:清屏CLRSCRN MACROPUSHREGMOV AH,6M
8、OV AL,0MOV BH,1FHMOV CX,0MOV DX,184FHINT 10HPOPREGENDM,16,;功能:置光标 ;入口参数:DH:DL 行,列 出口参数:无CURSOR MACROPUSH AXPUSH BXMOV AH,2XOR BH,BHINT 10HPOP BXPOP AXENDM,17,;功能:在指定位置显示指定颜色的字符 ;入口参数:X:行,Y:列,CHAR:字符,ATTRIB:颜色 ;出口参数:无PUTC MACRO X,Y,CHAR,ATTRIBPUSHREG ;宏嵌套MOV DH,XMOV DL,YCURSORMOV AH,09HMOV AL,CHARMOV
9、 BH,0MOV BL,ATTRIBMOV CX,1INT 10HPOPREG ;宏嵌套ENDM,18,;功能:在指定位置显示指定颜色的字符串 ;入口参数:以$结束的字符串变量S 出口参数:无 PUTS MACRO ROW,COL,S,ATTRIBLOCAL EXIT5LOCAL LOOP10PUSHREGMOV DH,ROWMOV DL,COLCURSORLEA BX,SMOV CX,80,19,LOOP10: MOV AL,BXCMP AL,$JE EXIT5PUTC DH,DL,AL,ATTRIBINC DLINC BXLOOP LOOP10 EXIT5: POPREGENDM,20,D
10、ATA SEGMENT STR DB PRINT A STRING.$ DATA ENDS CODE SEGMENTASSUME CS:CODE,DS:DATA MAIN PROC FARMOV AX,DATAMOV DS,AXCLRSCRN ;清屏MOV DH,10MOV DL,20PUTC DH,DL,$,1EH ;兰底黄INC DH ;行号加1;用兰底白字显示字符串PRINT A STRING.PUTS DH,DL,STR,1FHMOV AX,4C00HINT 21H MAIN ENDP CODE ENDSEND MAIN,21,五、宏指令嵌套,宏指令允许嵌套,嵌套情况有两种: 宏定义体
11、中含有宏调用 遵循先定义后引用的原则,后边的宏定义可以调用在它之前定义的宏指令 宏定义体中含有宏定义 只有调用了外层宏指令后才能调用内层宏指令,因为只有调用了外层的宏后,内层的宏定义才有效。,22,宏定义体中含有宏定义的宏定义、宏调用及宏替换的例子:,DMAC MACRO MNAME,OPER ;外层宏定义MNAME MACRO X,Y,Z ;内层宏定义PUSH AXMOV AX,XOPER AX,YMOV Z,AXPOP AXENDMENDM,23,A DW 25 B DW 12 C DW ?DMAC ADDITION,ADD ;外层宏调用 1 ADDITION MACRO X,Y,Z 1
12、PUSH AX 1 MOV AX,X 1 ADD AX,Y 1 MOV Z,AX 1 POP AX 1 ENDM ADDITION A,B,C ;内层宏调用 1 PUSH AX 1 MOV AX,A 1 ADD AX,B 1 MOV C,AX 1 POP AX,24,DMAC LOGIC_AND,AND ;外层宏调用 1 LOGIC_AND MACRO X,Y,Z 1 PUSH AX 1 MOV AX,X 1 AND AX,Y 1 MOV Z,AX 1 POP AX ENDM LOGIC_AND A,B,C ;内层宏调用 1 PUSH AX 1 MOV AX,A 1 AND AX,B 1 MO
13、V C,AX 1 POP AX,25,使用适当的实参数,通过调用DMAC宏指令可以生成另一条新的宏指令,再调用新宏指令可以实现任何双操作数指令的操作,而且两个操作数可以同时为存储器操作数。这种方法使得宏的功能更强大。,26,六、PURGE伪指令,格式:PURGE 宏指令名, 功能:从内存中删除指定的宏指令。,七、宏操作符,为使宏更灵活,汇编程序还支持宏操作符。这些操作符不仅适用于宏指令,也适用于重复汇编伪指令。宏操作符格式 名称注释 宏注释,27,1操作符&,在宏定义体中&可以作为形式参数的前缀,而当宏扩展时则把&前后两个符号合并形成一个符号,这个符号可以是操作码、操作数或是一个字符串。例6下
14、面定义的PutData宏指令中,参数TheName作为变量名的一部分,通过&把前后两个符号合并成一个变量名。在Jump宏指令中,参数Cond作为操作码的一部分,通过&把前后两个符号合并成一个指令助记符。,28, PUTDATA宏指令 PUTDATA MACRO THENAME, THEDATA PD_宏扩展1 JNE LAB1,29,在宏指令中,当使用宏扩展1 ?0001MYDATA DB 8,30,7.2 宏指令库,为了使宏指令能让多个程序共享,可以把它们组织到一个文件中,并存放在磁盘上,把这种文件称为宏指令库。 1建立宏指令库可以把一些常用的宏指令集中在一个文件中形成宏指令库,用EDIT等
15、任何文本编辑程序创建宏指令库,库名由用户自己起,而且对库的扩展名没有特殊要求。库中的宏指令以源代码形式出现。,31,例如用EDIT建立一个文件名为MACRO.LIB的宏指令库,键入以下命令:EDIT MACRO.LIB 假设MACRO.LIB中包含以下宏指令: SETMODE ;设置8025彩色显示模式 INCHAR ;接收一个字符,并返回在AL中 OUTCHAR X ;输出X字符 PUSHREG ;保存寄存器DX、CX、BX、AX、DI、SI、BP POPREG ;恢复寄存器BP、SI、DI、AX、BX、CX、DX,32,WINDOW MACROCollor,WleftTopRow,WLef
16、tTopCul, WRightBottomRow,WRightBottomCul;功能:开窗口 MOVE MOCRO X,Y ;字型数据X送Y变量 CLRSCRN ;清屏 CURSOR ;置光标,入口参数: DH:DL行,列号 MUL M1,M2 ;两个字型数据相乘 RETURN ;返回操作系统 BIN_DEC MACRO ASC,BIN ;功能:把16位二进制数转换为十进制数的 ;ASCII值,ASC为5个字节的十进制数缓冲区, ;BIN为要转换的二进制数。 DISP MACRO ASC ;显示首址为ASC的字符串,33,2把宏指令库包含到应用程序中 一旦建立了宏指令库,当要用到库中的宏指令
17、功能时,就可以使用INCLUDE伪指令把宏指令库包含到应用程序中。 格式:INCLUDE 源文件名 功能:把另一个源文件包含到当前源文件中。,34,说明:INCLUDE指示汇编程序把指定的文本文件从本行起加入汇编,直到该文本文件的最后一行汇编完后,继续汇编随后的语句。由于一个宏指令库中包含多条宏指令,使用INCLUDE后将把其中的所有宏指令包含到当前文件中,但其中的有些宏指令可能不是本文件所需要的,此时可以用PURGE伪指令从内存中删除那些不需要的宏指令,以释放它们所占的内存空间、减少开销。考虑到这些情况,每个宏指令库不应该设计得太大,一般把一些关系紧密的宏指令放在同一个库中。,35,3使用宏
18、指令库中的宏指令使用INCLUDE伪指令把宏指令库包含到应用程序后,就可调用其中的宏指令。例11实现32位二进制数除以16位二进制数,并把结果用十进制数形式显示在屏幕上。从下面的程序可以看出,利用宏指令库可以减少程序设计人员的工作量,使程序更简捷。,36,程序,INCLUDE MACRO.LIBPURGE SETMODE,INCHAR,OUTCHAR,WINDOW,MOVE,MUL STACKSG SEGMENT STACK SDW 16 DUP(?) STACKSG ENDS DATA SEGMENT A DD 7006652 ;被除数 B DW 1234 ;除数 C DW ? ;商 PRO
19、MPT DB The result is: $ ASCII DB 5 DUP(?),$ ;转换结果 DATA ENDS,37,CODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSG MAIN PROC FARMOV AX,DATAMOV DS,AXMOV DX,WORD PTR A+2MOV AX,WORD PTR ADIV B,38,BIN_DEC ASCII,AXCLRSCRNDISP PROMPTDISP ASCIIRETURN MAIN ENDP CODE ENDSEND MAIN,39,4. 宏指令与子程序的区别,采用宏和子程序均能达到代码共享、简
20、化源程序的目的,但它们的区别也是显而易见的。区别主要有以下几点: 参数的多样性及灵活性宏指令的实参数可以是常数、寄存器、内存变量、操作码或操作码的一部分、操作数的一部分等,这是子程序所不能比拟的。 参数传递的方便性 宏指令定义时可以带有形式参数,宏调用时可以直接在宏指令名后带有实参数以替换形式参数,因此宏指令参数的传递十分方便。而子程序参数的传递通过寄存器、堆栈等方法实现,实现起来不很方便。,40, 工作方式的区别宏调用汇编时由汇编程序来进行宏扩展,有多少次调用就需替换多少次,调用次数越多占用空间越大。子程序在程序执行期间由调用程序调用,是调用程序把控制权交给子程序执行后再返到调用程序,无论调
21、用多少次子程序都只占有自身大小的一份空间,执行CALL和RET指令要有一些时间开销。由于宏指令和子程序调用工作方式的区别,对于实现同一功能的程序段,使用宏指令占用较大空间但速度较快,使用子程序占用较小空间但执行时间较长。鉴于以上区别,编程时应该扬长避短地使用宏指令和子程序,通常宏指令被用在代码较短且参数较多的场合,子程序被用在代码较长的场合。,41,7.3 重复伪指令,当程序中需要重复书写相同或几乎相同的语句时,可以用重复伪指令定义重复块,以简化程序和减轻程序设计人员的工作量。绝大部分MASM版本提供了REPT、IRP和IRPC重复伪指令,而在MASM6.X中还提供了其它重复伪指令。,42,一
22、、重复伪指令REPT,格式:REPT 数值表达式 ;重复块ENDM功能:汇编程序使重复块的内容重复多次,重复次数由表达式给出。说明:重复块中可以出现任何有效的汇编语句,数值表达式的计算结果应该是无符号常数。,43,例1定义510的立方值。为了便于引用,把它定义在数据段,并定义变量名TABLE。,DATA SEGMENT TABLE LABEL WORDX=5REPT 6 ;重复6次DW X*X*X ;定义立方值X=X+1ENDM DATA ENDS,44,汇编后的情况如下: 1) 0000 DATA SEGMENT 2) 0000 TABLE LABEL WORD 3)=0005 X=5 4)
23、 REPT 6 5) DW X*X*X 6) X=X+1 7) ENDM,45,8)0000 007D 1 DW X*X*X9)0002 00D8 1 DW X*X*X10)0004 0157 1 DW X*X*X11)0006 0200 1 DW X*X*X12)0008 02D9 1 DW X*X*X13)000A 03E8 1 DW X*X*X14)000C DATA ENDS第8到第13行是汇编后的情况。在代码段中可以通过TABLE名来引用这些值。,46,例2重复块中可以包含指令。,MOV BX,10 REPT 2DEC BX ENDM 汇编后产生如下语句:MOV BX,10 1 DE
24、C BX 1 DEC BX,47,例3在屏幕上按升序输出26个大写字母。,CHARS MACRO NUMMOV AH,2CHAR=AREPT NUMMOV DL,CHARINT 21HCHAR=CHAR+1ENDMENDM,48,CODE SEGMENTASSUME CS:CODEMAIN PROC FARCHARS 26MOV AX,4C00HINT 21HMAIN ENDPCODE ENDSEND MAIN从本例可以看出,重复伪指令可以出现在宏指令中。,49,汇编后的列表文件如下所示:,CHARS MACRO NUMMOV AH,2CHAR=A REPT NUMMOV DL,CHARINT
25、 21HCHAR=CHAR+1ENDMENDM,50,0000 CODE SEGMENTASSUME CS:CODE 0000 MAIN PROC FARCHARS 26 0000 B4 02 1 MOV AH,2 0002 B2 41 2 MOV DL,CHAR ;字符A 0004 CD 21 2 INT 21H 0006 B2 42 2 MOV DL,CHAR ;字符B 0008 CD 21 2 INT 21H,51,0066 B2 5A 2 MOV DL,CHAR ;字符Z 0068 CD 21 2 INT 21H 006A B8 4C00 MOV AX,4C00H 006D CD 21
26、 INT 21H 006F MAIN ENDP 006F CODE ENDSEND MAIN,52,二、不定重复伪指令,1IRP伪指令格式:IRP 形式参数,实参数 ;重复块ENDM功能:汇编程序使重复块的内容重复多次,重复次数由实参数个数决定。每次重复都用尖括号中的一个实参数替代形式参数,依次使用实参数,直到用完为止。,53,说明:重复块中可以出现任何有效的汇编语句。实参数可以是有效的符号、字符串、数字或运算常数。例1实参数可以是符号。IRP REG,PUSH REGENDM汇编后产生以下指令:1 PUSH AX1 PUSH BX1 PUSH CX1 PUSH DX,54,例2实参可以是数字
27、、常数表达式或字符串,IRP X,DB XENDM 汇编后产生的.LST文件: 0000 01 1 DB 1 ;数字 0001 02 1 DB 2 ;数字 0002 08 1 DB 3+5 ;常数表达式 0003 45 44 49 54 1 DB EDIT ;ASCII值从目标码部分可以看出,数字1、2生成01、02,3+5计算后其值为8,EDIT生成相应的ASCII值45、44、49、54。,55,2IRPC伪指令,格式:IRPC 形式参数,数字串 ;重复块ENDM功能:汇编程序使重复块的内容重复多次,重复次数由数字串中数字位数决定。每次重复都用数字串中一个数字替代形参,依次使用串中的数字,
28、直到用完为止。说明:重复块中可以出现任何有效的汇编语句。,56,例1定义一串数字。IRPC Z,1235DB ZENDM汇编后生成的.LST文件如下:0001 01 1 DB 10002 02 1 DB 20003 03 1 DB 30004 05 1 DB 5 可以看出,目标代码列生成数字01、02、03、05。注意形参的位置只能是数字串,若为字符串则其中的字符必须是符号,否则汇编出错。,57,例2形式参数不能是字符串示例。,IRPC M,ABCDB MENDM 汇编后生成的.LST文件如下: 0001 00 1 DB A IRP.ASM(14):error A2009:Symbol not
29、 defined:A 0002 00 1 DB B IRP.ASM(14):error A2009:Symbol not defined:B 0003 00 1 DB C IRP.ASM(14):error A2009:Symbol not defined:C由于汇编程序把其中的字符当做符号,而这些符号又未定义,所以出错。,58,例3把寄存器内容入栈。,IRPC K,ABCDPUSH K&XENDM 汇编后生成的.LST文件如下: 0000 50 1 PUSH AX 0001 53 1 PUSH BX 0002 51 1 PUSH CX 0003 52 1 PUSH DX,59,7.4 条件伪
30、指令,汇编语言提供一组条件汇编伪指令,使用它们可以决定把一段代码是否包含在程序内,从而提高汇编效率。条件伪指令的一般格式:IFxx 自变量ELSEENDM,60,功能:如果条件为真,汇编程序汇编直到ELSE以前的条件块,若无ELSE,则汇编直到ENDIF之前的条件块;如果条件为假,汇编程序汇编ELSE后面的条件块,若无ELSE,则不生成条件块。 注意:自变量必须在汇编程序第一遍扫描后成为确定的数值。 下表给出了汇编语言的条件伪指令及其功能。,61,62,后四个伪指令IFxxx和IFxxxI 的区别是IFxxxI 在比较字符时忽略大小写。 条件伪指令与宏定义配合很有用,但并不限于此。它可以用在宏
31、定义体外,也允许嵌套任意次。一个宏定义可以包含检测一系列条件的条件伪指令。在有些情况下,如果条件为真,要求汇编程序从进一步的宏扩展中退出,这时可以用EXITM伪指令。,63,ALL_LT_50 MACRO LENTHVALUE=0IF LNGTH GE 50EXITMENDIFREPT LNGTHVALUE=VALUE+1DB VALUEENDM ENDM这个宏定义仅当LNGTH小于50时才分配表空间。在宏扩展过程中,若汇编程序遇到EXITM,则终止宏扩展,并在ENDM伪指令后重新开始。,64,例1根据处理器型号的不同,执行不同的移位指令序列。,.386 PROCESSOR = 80386 I
32、F PROCESSOR EQ 80386SHL AX,4 ELSE MOV CL,4SHL AX,CL ENDIF 汇编生成的列表文件如下:.386 =00013A02 PROCESSOR=80386IF PROCESSOR EQ 80386 0000 66| C1 E0 04 SHL AX,4 ENDIF,65,例2IFB和IFNB条件伪指令常用于宏指令中,以检查一个操作数是空(IFB)或不空(IFNB),DISPLAY MACRO FUNCTION,ADDRESS,CHARMOV AH,FUNCTIONIFB MOV DL,&CHARELSELEA DX,ADDRESSENDIFINT 2
33、1H ENDM,66,CODE SEGMENTMAIN PROC FARASSUME CS:CODE,DS:CODEMOV AX,CODEMOV DS,AXDISPLAY 9,OP3 ;参数2不空,调用21H中断9号功能DISPLAY 2,E ;参数2为空,调用21H中断2号功能MOV AX,4C00HINT 21HOP3 DB ABC$MAIN ENDPCODE ENDSEND MAIN,67,例3IFIDN、IFIDNI、IFDIF和IFDIFI条件伪指令常用于宏指令中检查两个字符串是否相等,IDT MACRO OPD ;定义宏 IFIDN ,ADD AX,1 ;1 若则汇编 ENDIF IFIDNI ,ADD AX,2 ;2 忽略大小写时;若则汇编 ENDIF,68,IFDIF ,ADD AX,3 ;3 若则汇编 ENDIF IFDIFI ,ADD AX,4 ;4 忽略大小写时;若则汇编 ENDIFENDM,69,CODE SEGMENT MAIN PROC FARASSUME CS:CODE,DS:CODEMOV AX,CODEMOV DS,AX.LALLIDT ADD ;第一次调用IDT ADD ;第二次调用IDT SUB ;第三次调用MOV AX,4C00HINT 21H MAIN ENDP CODE ENDSEND MAIN,