子程序与宏指令设计.ppt

上传人:小飞机 文档编号:6564271 上传时间:2023-11-13 格式:PPT 页数:129 大小:300KB
返回 下载 相关 举报
子程序与宏指令设计.ppt_第1页
第1页 / 共129页
子程序与宏指令设计.ppt_第2页
第2页 / 共129页
子程序与宏指令设计.ppt_第3页
第3页 / 共129页
子程序与宏指令设计.ppt_第4页
第4页 / 共129页
子程序与宏指令设计.ppt_第5页
第5页 / 共129页
点击查看更多>>
资源描述

《子程序与宏指令设计.ppt》由会员分享,可在线阅读,更多相关《子程序与宏指令设计.ppt(129页珍藏版)》请在三一办公上搜索。

1、第六章 子程序与宏指令设计,为了程序共享或模块化设计的需要,可以把一段公共语句序列设计成子程序或宏指令的形式。,6.1 子程序结构及设计方法6.2 子程序参数传递6.3 嵌套与递归子程序6.4 宏 指 令6.5 宏指令库6.6 重复伪指令6.7 条件伪指令,6.1 子程序结构及设计方法,6.1.1 含有子程序的程序结构在汇编语言中用过程定义伪指令定义子程序。过程定义伪指令格式:过程名PROC 属型过程名ENDP,1调用程序和子程序在同一个代码段的程序结构(子程序类型可缺省,注意END后必须跟主程序名)CODE SEGMENTMAINPROC FARCALLSUB1RETMAINENDPSUB1

2、PROCRETSUB1ENDPCODEENDSENDMAIN,2调用程序和子程序在不同段的程序结构(SUB2既被段间调用又被段内调用,必须是FAR属性。CALL要显式说明是FAR属性)CODE1SEGMENTMAINPROC FARCALLFAR PTR SUB2RETMAINENDPCODE1ENDSCODE2SEGMENTSUB1PROCFARCALL FAR PTR SUB2RETSUB1ENDPSUB2PROCFARRETSUB2ENDPCODE2ENDSENDMAIN,6.1.2 设计子程序时应注意的问题1子程序说明2寄存器的保存与恢复3密切注意堆栈状态,6.2 子程序参数传递,可以

3、通过给子程序传递参数使其更通用。常用的参数传递方法如下:通过寄存器传递;若调用程序和子程序在同模块(源程序)中,子程序可以直接访问模块中的变量;通过地址表传递参数地址;通过堆栈传递参数或参数地址。,6.2.1 通过寄存器传递这种传递方式使用方便,适用于参数较少的情况。例1把BX中的16位二进制数转换成十进制并显示在屏幕上。,STASGSEGMENTDW 32 DUP(?)STASG ENDSCODE SEGMENTASSUME CS:CODEMAIN PROC FARMOV BX,162EHCALL TERN MOV AX,4C00H INT 21HMAIN ENDP,程序6.3,TERN P

4、ROC;二十并显示。MOV CX,10000CALL DEC_DIV;转换万位数 MOV CX,1000CALL DEC_DIV;转换千位数 MOV CX,100CALL DEC_DIV;转换百位数 MOV CX,10CALL DEC_DIV;转换十位数 MOV CX,1CALL DEC_DIV;转换个位数RETTERN ENDP,DEC_DIVPROC;CX中为十进制的位权MOV AX,BXMOV DX,0 DIV CX;商为转换后的一位十进制数MOV BX,DXMOV DL,AL ADD DL,30H;转换成ASCII码 MOV AH,2;显示INT 21H RETDEC_DIVENDPC

5、ODE ENDS END MAIN,6.2.2 同模块中的子程序可直接访问模块中的变量 若调用程序和子程序在同模块中,子程序可以直接访问模块中的变量。例2实现数组求和功能。要求数组求和(不考虑溢出情况)由子程序实现,其数组元素及结果均为字型数据。见程序6.4。,STACKSGSEGMENT STACK STKDW 32 DUP(S)STACKSG ENDSDATA SEGMENTARY DW 1,2,3,4,5,6,7,8,9,10COUNT DW($-ARY)/2;数组元素个数SUM DW?;数组和的地址DATA ENDS,程序6.4,CODE1 SEGMENTMAIN PROC FAR A

6、SSUME CS:CODE1,DS:DATA PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX CALL FAR PTR ARY_SUM RETMAIN ENDPCODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2ARY_SUM PROC FAR;数组求和子程序 PUSH AX;保存寄存器 PUSH CX PUSH SI LEA SI,ARY;取数组起始地址 MOV CX,COUNT;取元素个数 XOR AX,AX;清0累加器,NEXT:ADD AX,SI;累加和 ADD SI,TYPE ARY;修改地址指针 LOOP

7、NEXT MOV SUM,AX;存和 POP SI;恢复寄存器 POP CX POP AX RET ARY_SUM ENDPCODE2 ENDS END MAIN,6.2.3 通过地址表传递参数地址适用于参数较多的情况。具体方法是先建立一个地址表,该表由参数地址构成。然后把表的首地址通过寄存器或堆栈传递给子程序。例3编写一个数组求和子程序,其数组元素及结果均为字型数据。另定义两个数组,并编写一个主程序,通过调用数组求和子程序分别求出两个数组的和。见程序6.5。,程序6.5,STACKSG SEGMENT STACK STK DW 32 DUP(S)STACKSG ENDSDATA SEGMEN

8、TARY DW 1,2,3,4,5,6,7,8,9,10;数组1COUNT DW($-ARY)/2;数组1的元素个数SUM DW?;数组1的和地址NUM DW 10,20,30,40,50;数组2CT DW($-NUM)/2;数组2的元素个数TOTAL DW?;数组2的和地址TABLE DW 3 DUP(?);地址表DATA ENDS,CODE1SEGMENTMAINPROC FAR ASSUME CS:CODE1,DS:DATA PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX;构造数组1的地址表 MOV TABLE,OFFSET ARY MOV

9、 TABLE+2,OFFSET COUNT MOV TABLE+4,OFFSET SUM LEA BX,TABLE;传递地址表首地址 CALL FAR PTR ARY_SUM,;构造数组2的地址表 MOV TABLE,OFFSET NUM MOV TABLE+2,OFFSET CT MOV TABLE+4,OFFSET TOTAL LEA BX,TABLE;传递地址表的首地址 CALL FAR PTR ARY_SUM;段间调用调用数组求和子程序 RETMAIN ENDPCODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2ARY_SUM PROC FAR;数组求和子程

10、序 PUSH AX;保存寄存器 PUSH CX PUSH SI PUSH DI MOV SI,BX;取数组起始地址 MOV DI,BX+2;取元素个数地址 MOV CX,DI;取元素个数 MOV DI,BX+4;取结果地址 XOR AX,AX;清0累加器,NEXT:ADD AX,SI;累加和 ADD SI,TYPE ARY;修改地址指针 LOOP NEXT MOV DI,AX;存和 POP DI;恢复寄存器 POP SI POP CX POP AX RET ARY_SUM ENDPCODE2 ENDS END MAIN,6.2.4 通过堆栈传递参数或参数地址这种方式适用于参数较多,或子程序有多

11、层嵌套、递归调用的情况。步骤:主程序把参数或参数地址压入堆栈;子程序使用堆栈中的参数或通过栈中参数地址取到参数;子程序返回时使用RET n指令调整SP指针,以便删除堆栈中已用过 的参数,保持堆栈平衡,保证程序的正确返回。,例4完成数组求和功能,求和由子程序实现,要求通过堆栈传递参数地址。STACKSG SEGMENT STACK STK DW 16 DUP(?)STACKSG ENDSDATA SEGMENTARY DW 1,2,3,4,5,6,7,8,9,10COUNT DW($-ARY)/2SUM DW?DATA ENDS,程序6.6,CODE1 SEGMENTMAIN PROC FAR

12、ASSUME CS:CODE1,DS:DATA PUSH DS;XOR AX,AX PUSH AX;MOV AX,DATA MOV DS,AX,LEA BX,ARY PUSH BX;压入数组起始地址 LEA BX,COUNT PUSH BX;压入元素个数地址 LEA BX,SUM PUSH BX;压入和地址 CALL FAR PTR ARY_SUM;调用求和子程序 RET;MAIN ENDPCODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2ARY_SUM PROC FAR;数组求和子程序 PUSH BP;保存BP值 MOV BP,SP;BP是堆栈数据的地址指针 P

13、USH AX;保存寄存器内容 PUSH CX;PUSH SI;PUSH DI;MOV SI,BP+10;得到数组起始地址 MOV DI,BP+8;得到元素个数地址 MOV CX,DI;得到元素个数 MOV DI,BP+6;得到和地址 XOR AX,AX,NEXT:ADD AX,SI;累加 ADD SI,TYPE ARY;修改地址指针 LOOP NEXT MOV DI,AX;存和 POP DI;恢复寄存器内容 POP SI;POP CX;POP AX;POP BP;RET 6;返回并调整SP指针ARY_SUM ENDPCODE2 ENDS END MAIN,返回,程序6.6中所有入栈操作对堆栈的

14、影响,返回,程序6.6中主程序的RET执行前堆栈状态,例5完成数组求和功能,其中求和由子程序实现,要求使用结构访问堆栈中的参数。编码见程序6.7。,返回,SS,SP,BP,程序6.7的堆栈及结构数据示意图,结构,程序6.7,STACKSG SEGMENT STACK STK DW 16 DUP(S)STACKSG ENDSDATA SEGMENTARY DW 1,2,3,4,5,6,7,8,9,10COUNT DW($-ARY)/2SUM DW?DATA ENDS,CODE1 SEGMENTMAIN PROC FAR ASSUME CS:CODE1,DS:DATA PUSH DS XOR AX

15、,AX PUSH AX MOV AX,DATA MOV DS,AX,LEA BX,ARY PUSH BX;压入数组起始地址 LEA BX,COUNT PUSH BX;压入元素个数地址 LEA BX,SUM PUSH BX;压入和地址 CALL FAR PTR ARY_SUMRETMAIN ENDPCODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2STACK_STRC STRUC;定义结构SAVE_BP DW?SAVE_CS_IP DW 2 DUP(?)SUM_ADDR DW?COUNT_ADDR DW?ARY_ADDR DW?STACK_STRC ENDS,ARY

16、_SUMPROC FAR;数组求和子程序 PUSH BP;保存BP值 MOV BP,SPPUSH AX PUSH CX PUSH SI PUSH DI MOV SI,BP.ARY_ADDR;数组始地址 MOV DI,BP.COUNT_ADDR MOV CX,DI MOV DI,BP.SUM_ADDR;得到和地址 XOR AX,AX,NEXT:ADD AX,SI;累加 ADD SI,TYPE ARY;修改地址指针 LOOP NEXT MOV DI,AX;存和 POP DI POP SI POP CX POP AX POP BP RET 6;返回并调整SP指针ARY_SUM ENDPCODE2 E

17、NDS END MAIN,子程序嵌套示意图,返回,6.3 嵌套与递归子程序,1.子程序嵌套,以下是求N!递归过程的描述。编码见程序6.8。,2.递归子程序,BEGINFACT(N,RESULT)SAVEREGISTER ON STACKIF N=0RESULT1ELSEPUSH ADDRESS OF RESULT ONTO STACKPUSH N-1 ONTO STACKCALL FACT(N-1,RESULT)RESULTN*RESULTENDIFRESTORE REGISTERS FROM STACKDELETE PARAMETERS FROM STACK,N!流程图,返回,程序6.8,S

18、TACKSG SEGMENTSTACK S;定义堆栈DW 128 DUP(ST)STACKSG ENDSDATA SEGMENTN_VAL DW3;定义N值RESULT DW?;结果DATA ENDS,CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKSGFRAMESTRUC;定义帧结构SAV_BPDW?;保存BP值SAV_CS_IPDW 2 DUP(?);保存返回地址NDW?;当前N值RESULT_ADDRDW?;结果地址FRAMEENDS,MAIN PROCFAR MOVAX,DATA MOVDS,AX LEABX,RESULT PUSHBX;结果地址

19、入栈 PUSHN_VAL;N值入栈 CALLFARPTRFACT;调用递归子程序R1:MOVAX,4C00H INT21HMAIN ENDP,FACTPROC FAR;N!递归子程序 PUSH BP;保存BP值 MOV BP,SP;BP指向帧基地址 PUSH BX PUSH AX MOV BX,BP.RESULT_ADDRMOV AX,BP.N;取帧中N值 CMP AX,0 JE DONE;N0时退出子程序嵌套 PUSH BX;为下一次调用压入结果地址 DEC AX PUSH AX;为下一次调用压入(N1)值 CALL FAR PTR FACT,R2:MOVBX,BP.RESULT_ADDR

20、MOVAX,BX;取中间结果(N1)!MULBP.N;N*(N1)!JMPSHORT RETURNDONE:MOVAX,1;0!1RETURN:MOVBX,AX;存中间结果 POP AX POP BX POP BP RET 4FACT ENDPCODE ENDS END MAIN,程序6.8的运行情况:主程序把结果地址和N的初始值压入堆栈,然后调用FACT子程序。在FACT中,它不断调用自身,每调用一次都要在堆栈中形成一帧,该帧由以下信息组成:子程序中要用到的寄存器内容、中间结果地址、(N1)的值、子程序返回地址,自身调用直到N0为止。,当N0时开始返回。通过BP.RESULT_ADDR和BP

21、.N取出堆栈中本次使用的参数,计算N*(N-1)!的值,保存中间结果,恢复寄存器的值,用RET 4返回并废除已用过的N和中间结果地址。重复第步,逐层返回直到N等于初始值为止。,6.4 宏 指 令,在高级汇编语言技术中,一段共用语句序列除了可以设计成子程序外,还可以设计成宏指令的形式。,6.4.1 宏定义、宏调用、宏扩展,宏指令是源程序中一段有独立功能的程序代码。宏指令由宏定义伪指令定义,它只需在源程序中定义一次,便可以多次被调用。,宏指令名 MACRO 形式参数表;宏指令体ENDM,宏定义伪指令格式:,宏调用,宏指令一经定义,就可以在程序中调用它,这被称为宏调用。宏调用格式:宏指令名 实参数表

22、,宏扩展,宏扩展就是用宏定义体替换宏指令名,并用实参数替换形式参数。,例1输入一个字符的宏定义、宏调用、宏扩展,;宏定义INCHARMACROMOVAH,1 INT21H;输入的字符在ALENDM;宏调用 INCHAR当汇编程序汇编到宏指令INCHAR时,则对其扩展如下:1 MOV AH,11 INT 21H,指令前的“1”表示该语句是扩展时替换得到的。,设计宏指令时应注意的问题,由于宏指令也像子程序那样可以被多次调用或被多个程序共享,所以在设计时需要注意以下问题:1宏指令说明 2寄存器的保存与恢复 3宏指令中的符号说明,6.4.2 LOCAL伪指令,格式:LOCAL 局部符号表功能:对局部符

23、号表中的每个符号,在汇编时每扩展一次便建立一个惟一的符号,形如?xxxx(xxxx的值在0000FFFF之间)。以保证汇编时生成名字的惟一性。,例2以下是定义一个延时程序的宏指令delay,并且在同一个程序中两次被调用的扩展情况。,;宏定义DELAYMACROLOCALLOPMOVCX,2801LOP:LOOPLOPENDM,宏调用:DELAYDELAY汇编时宏扩展如下:DELAY0009 B9 0AF11 MOV CX,2801 000C E2 FE1?0000:LOOP?0000 DELAY000E B9 0AF11 MOV CX,2801 0011 E2 FE1?0001:LOOP?00

24、01,宏指令中参数的使用,在宏定义时可以带有形式参数,而在宏调用时给出实参数即可。宏指令的参数可以是常数、寄存器、变量、表达式、操作码或操作码的一部分、指令或伪指令助记符等。,例3定义在两个字型内存变量之间传送数据的宏指令,并调用它,然后观察其扩展情况。,MOVEMOCROX,YPUSHAXMOVAX,XMOVY,AXPOPAXENDM,DATA SEGMENTVAR1 DW 6543HVAR2 DW?DATA ENDS;宏调用;宏扩展 MOVE VAR1,VAR2 1 PUSHAX1 MOV AX,VAR11 MOV VAR2,AX1 POP AX,6.4.3 宏指令嵌套,宏指令嵌套有两种情

25、况:宏定义体中含有宏调用;宏定义体中含有宏定义。,DMACMACROMNAME,OPER;外层宏定义MNAMEMACRO X,Y,Z;内层宏定义PUSH AXMOV AX,XOPER AX,YMOV Z,AXPOP AXENDMENDM,例4宏定义体中嵌套宏定义的宏指令、宏调用及宏扩展示例。,ADW25BDW12CDW?DMAC ADDITION,ADD;外层宏调用1ADDITION MACRO X,Y,Z1 PUSH AX1 MOV AX,X1 ADD AX,Y1 MOV Z,AX1 POP AX1 ENDM,ADDITION A,B,C;内层宏调用1 PUSH AX1 MOV AX,A1

26、ADD AX,B1 MOV C,AX1 POP AX,DMAC LOGIC_AND,AND;外层宏调用1LOGIC_AND MACROX,Y,Z1 PUSHAX1 MOVAX,X1 ANDAX,Y1 MOVZ,AX1 POPAX1 ENDM,LOGIC_AND A,B,C;内层宏调用1 PUSH AX1 MOV AX,A1 AND AX,B1 MOV C,AX1 POP AX 使用适当的实参数,通过调用DMAC宏指令可以生成另一条新的宏指令,再调用新宏指令可以实现任何双操作数指令的操作,而且两个操作数可以同时为存储器操作数。这种方法使得宏的功能更强大。,PURGE伪指令,格式:PURGE 宏指

27、令名,功能:从内存中删除指定的宏指令。例:PURGE INCHAR,6.4.4 宏操作符,这些操作符不仅适用于宏指令,也适用于重复汇编伪指令。宏操作符格式名称 注释 宏注释,1操作符&,在宏定义体中&可以作为形式参数的前缀,而当宏扩展时则把&前后两个符号合并形成一个符号,这个符号可以是操作码、操作数或是一个字符串。例5下面定义的PutData宏指令中,参数TheName作为变量名的一部分,通过&把前后两个符号合并成一个变量名。在Jump宏指令中,参数Cond作为操作码的一部分,通过&把前后两个符号合并成一个指令助记符。,PUTDATA宏指令PUTDATA MACROTHENAME,THEDAT

28、A PD_宏扩展 1 PD_MYDATA DB 5,JUMP宏指令 JUMPMACROCOND,LJ宏扩展1JNE LAB1,在宏指令中,当使用宏定义PUTDATA0 MACRO THENAME,THEDATA LOCAL PD_&THENAME PD_&THENAME DBTHEDATA ENDM,;宏调用PUTDATA0 MYDATA,5;宏扩展1?0000MYDATA DB 5;宏调用PUTDATA0 MYDATA,8;宏扩展1?0001MYDATA DB 8,返回,由操作符括起的内容作为一个整体原样传递。例如,可以使用符号包围目标,从而使该目标作为单一的参数而不是多个参数的列表。例6用

29、不同的实参数调用PUTDATA宏指令,观察它们的变化。PUTDATA MACRO THENAME,THEDATAPD_宏扩展 1 PD_MYDATA DB 5,2文本原样传递操作符,;宏调用2PUTDATA MYDATA,;宏扩展1PD_MYDATA DB 5,4,3,又如以下符号定义语句:Numeric=10+2Textual equ 其汇编结果是:NUMERIC.NUMBER 000CTEXTUAL.TEXT 10+2可以看到,对Numeric已经求值,而Textual只是一串字符而已。,返回,3字符原意操作符!,!操作符指示MASM把后跟的一个字符原样传送,即把它只作为普通字符对待。例如

30、,若你需要把“!&%”符号中的一个作为宏指令中的字符,可以使用!操作符。,例7以下宏调用的第二个实参数是一串警告信息,其中最后一个字符希望是感叹号“!”。但“!”是宏操作符,要想把“!”当做其原意感叹号对待,就需在它前边加上宏操作符!。,;宏定义DEBUGMSG MACRO POINT,STRINGMSG宏扩展1MSG6 DB AT POINT 6:INSERTION FAILS!,4表达式操作符,在宏调用时,操作符强迫后跟的表达式立即求值,并把表达式的结果作为实参数替换,而不是表达式本身。例8定义Problem1宏指令,并比较两次调用Problem1宏指令的区别,其中一次调用中使用了操作符。

31、Problem1宏指令功能:把由宏指令参数所指定的字型数组(array)的一个元素装入AX寄存器,该参数经汇编后必须是一个常数表达式。,PROBLEM1 MACRO PARAMETER MOV AX,ARRAYPARAMETER*2 ENDM;宏调用1:希望取出ARRAY12,其中的参数10+2是表达式本身 PROBLEM1 10+2;宏扩展1:1 MOV AX,ARRAY10+2*2;实际取出的是ARRAY7,正确的表达是:;宏调用2:PROBLEM1%10+2;宏扩展2:1 MOV AX,ARRAY12*2,注意:由于MASM在调用宏指令时对其中的参数经常是原文替换,所以有时产生的可能不是

32、预期的结果。,考虑以下对PROBLEM1的宏调用及宏扩展:;宏调用,要求装入ARRAY的元素2PROBLEM1 2;宏扩展1MOV AX,ARRAY2*2可以看到,宏扩展后结果正确。,;宏调用:装入ARRAY的元素10:INDEX=8PROBLEM1 INDEX+2;宏扩展 1MOV AX,ARRAYINDEX+2*2因为MASM的地址表达式遵守操作符优先级的优先规则,则该语句宏扩展后不是预想的结果,它访问的是元素6(索引12),而不是元素10(索引20)。,为了能够得到正确的结果,可以在宏指令的参数表达式中用()把参数括起来:;宏定义PROBLEM2 MACRO PARAMETER MOV

33、AX,ARRAY(PARAMETER)*2 ENDM;宏调用 INDEX=8 PROBLEM2 INDEX+2;宏扩展1MOV AX,ARRAY(INDEX+2)*2,5宏注释;,在宏定义中,若注释以一个分号开始,则该注释在宏扩展时出现。但若注释以两个分号开始,则该注释在宏扩展时不出现。举例见列表伪指令。,返回,6.4.5 列表伪指令,格式 功能.LALL 在列表文件中列出全部宏文本内容(以双分号开头的注释除外).SALL 在列表文件中不显示任何宏文本内容.XALL(缺省)在列表文件中只列出可产生 目标代码的宏文本内容注意:这些列表伪指令只影响列表文件,并不影响目标码的生成。,6.5 宏指令库

34、,为了使宏指令能让多个程序共享,可以把它们组织到一个文件中,并存放在磁盘上,把这种文件称为宏指令库。1.建立宏指令库可以把一些常用的宏指令集中在一个文件中形成宏指令库,用EDIT等任何文本编辑程序创建宏指令库,库名由用户自己起,而且对库的扩展名没有特殊要求。库中的宏指令以源代码形式出现。,假设MACRO.LIB中包含以下宏指令(详细内容见教材P174):SETMODE;设置8025彩色显示模式INCHAR;接收一个字符,并返回在AL中OUTCHAR X;输出X字符PUSHREG;保存寄存器DX、CX、BX、AX、DI、SI、BPPOPREG;恢复寄存器BP、SI、DI、AX、BX、CX、DX,

35、WINDOW MACROCollor,WleftTopRow,WLeftTopCul,WRightBottomRow,WRightBottomCul;功能:开窗口MOVE MOCRO X,Y;字型数据X送Y变量CLRSCRN;清屏CURSOR;置光标,入口参数:DH:DL行,列号RETURN;返回操作系统,BIN_DECMACROASC,BIN;功能:把16位二进制数转换为十进制数的;ASCII值,ASC为5个字节的十进制数缓冲区,;BIN为要转换的二进制数。DISP MACRO ASC;显示首址为ASC的字符串,2把宏指令库包含到应用程序中格式:INCLUDE 源文件名功能:把另一个源文件包

36、含到当前 源文件中。,3使用宏指令库中的宏指令 例9实现32位二进制数除以16位二进制数,并把结果用十进制数形式显示在屏幕上。编码见程序6.9。,程序6.9,INCLUDEMACRO.LIBPURGESETMODE,INCHAR,OUTCHAR,WINDOW,MOVE,MULSTACKSGSEGMENTSTACK SDW16DUP(?)STACKSGENDSDATASEGMENTADD7006652;被除数BDW1234;除数CDW?;商PROMPTDBThe result is:$ASCIIDB5DUP(?),$;转换结果DATAENDS,CODESEGMENTASSUMECS:CODE,D

37、S:DATA,SS:STACKSGMAINPROCFARMOVAX,DATAMOVDS,AXMOVDX,WORD PTR A+2MOVAX,WORD PTR ADIVB,BIN_DECASCII,AXCLRSCRNDISPPROMPTDISPASCIIRETURNMAINENDPCODEENDSENDMAIN,4.宏指令与子程序的区别,采用宏和子程序均能达到代码共享、简化源程序的目的,但它们的区别也是显而易见的。区别主要有以下几点:,(1)工作方式的区别(2)参数传递的方便性(3)参数的多样性及灵活性,通常:宏指令被用在代码较短且参数 较多的场合;子程序被用在代码较长的场合。,6.6 重复伪指

38、令,当程序中需要重复书写相同或几乎相同的语句时,可以用重复伪指令定义重复块,以简化程序和减轻程序设计人员的工作量。绝大部分MASM版本提供了REPT、IRP和IRPC重复伪指令,而在MASM6.X中还提供了其它重复伪指令。,6.6.1 重复伪指令REPT,格式:REPT 数值表达式;重复块ENDM功能:汇编程序使重复块的内容重复多次,重复次数由表达式给出。说明:重复块中可以出现任何有效的汇编语句,数值表达式的计算结果应该是无符号常数。,DATASEGMENTTABLELABELWORDX=5REPT 6;重复6次DW X*X*X;定义立方值X=X+1ENDMDATAENDS,汇编后的情况如下:

39、(1)0000 DATA SEGMENT(2)0000 TABLELABEL WORD(3)=0005 X=5(4)REPT 6(5)DW X*X*X(6)X=X+1(7)ENDM,(8)0000007D1DWX*X*X(9)000200D81DWX*X*X(10)000401571DWX*X*X(11)000602001DWX*X*X(12)000802D91DWX*X*X(13)000A03E81DWX*X*X(14)000CDATA ENDS第(8)到第(13)行是汇编后的情况。在代码段中可以通过TABLE名来引用这些值。,MOV BX,10REPT 2 DEC BXENDM汇编后产生如

40、下语句:MOV BX,101DEC BX1DEC BX,CHARSMACRONUMMOVAH,2CHAR=AREPT NUMMOV DL,CHARINT 21HCHAR=CHAR+1ENDMENDM,CODESEGMENTASSUMECS:CODEMAINPROCFARCHARS26MOVAX,4C00HINT21HMAINENDPCODEENDSENDMAIN从本例可以看出,重复伪指令可以出现在宏指令中。,CHARSMACRONUMMOVAH,2CHAR=A REPTNUMMOV DL,CHARINT 21HCHAR=CHAR+1ENDMENDM,0000CODE SEGMENT ASSUM

41、E CS:CODE0000MAINPROC FAR CHARS 260000 B4 021MOV AH,20002 B2 412MOV DL,CHAR;字符A0004 CD 212INT 21H0006 B2 422MOV DL,CHAR;字符B0008 CD 212INT 21H,0066 B2 5A2MOV DL,CHAR;字符Z0068 CD 212INT 21H006A B8 4C00MOV AX,4C00H006D CD 21INT 21H006FMAINENDP006FCODEENDSENDMAIN,6.6.2 不定重复伪指令,1IRP伪指令格式:IRP 形式参数,实参数;重复块E

42、NDM功能:汇编程序使重复块的内容重复多次,重复次数由实参数个数决定。每次重复都用尖括号中的一个实参数替代形式参数,依次使用实参数,直到用完为止。,例1实参数可以是符号。IRP REG,PUSH REG ENDM汇编后产生以下指令:1 PUSH AX 1 PUSH BX 1 PUSH CX 1 PUSH DX,IRP X,DB X ENDM汇编后产生的.LST文件:0000 011 DB 1;数字0001 021 DB 2;数字0002 081 DB 3+5;常数表达式0003 45 44 49 54 1 DB EDIT;ASCII值从目标码部分可以看出,数字1、2生成01、02,3+5计算后

43、其值为8,EDIT生成相应的ASCII值45、44、49、54。,2IRPC伪指令,格式:IRPC形式参数,数字串;重复块ENDM功能:汇编程序使重复块的内容重复多次,重复次数由数字串中数字位数决定。每次重复都用数字串中一个数字替代形参,依次使用串中的数字,直到用完为止。说明:重复块中可以出现任何有效的汇编语句。,例2定义一串数字。IRPC Z,1235 DB Z ENDM汇编后生成的.LST文件如下:0001 011DB10002 021DB20003 031DB30004 051DB5 可以看出,目标代码列生成数字01、02、03、05。注意形参的位置只能是数字串,若为字符串则其中的字符必

44、须是符号,否则汇编出错。,IRPC K,ABCD PUSHK&X ENDM 汇编后生成的.LST文件如下:0000 501PUSH AX0001 531PUSH BX0002 511PUSH CX0003 521PUSH DX,6.7 条件伪指令,一般格式:IFxx 自变量 ELSE ENDM注意:自变量必须在汇编程序第一遍扫描后成为确定的数值。,后四条伪指令IFxxx和IFxxxI 的区别是:IFxxxI 在比较字符时忽略大小写。,ALL_LT_50MACRO LENTHVALUE=0IFLNGTH GE 50EXITMENDIFREPTLNGTHVALUE=VALUE+1DB VALUEE

45、NDMENDM这个宏定义仅当LNGTH小于50时才分配表空间。在宏扩展过程中,若汇编程序遇到EXITM,则终止宏扩展,并在ENDM伪指令后重新开始。,.386PROCESSOR=80386 IF PROCESSOR EQ 80386 SHL AX,4 ELSE MOV CL,4 SHL AX,CL ENDIF,汇编生成的列表文件如下:.386=00013A02PROCESSOR=80386IF PROCESSOR EQ 80386 0000 66|C1 E0 04SHL AX,4 ENDIF,DISPLAYMACROFUNCTION,ADDRESS,CHARMOVAH,FUNCTIONIFBM

46、OVDL,&CHARELSELEADX,ADDRESSENDIFINT 21HENDM,CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:CODE MOV AX,CODE MOV DS,AX DISPLAY 9,OP3;参数2不空,调用21H中断9号功能 DISPLAY 2,E;参数2为空,调用21H中断2号功能 MOV AX,4C00H INT 21H OP3 DB ABC$MAIN ENDP CODE ENDS END MAIN,IDTMACRO OPD;定义宏IFIDN,ADD AX,1;1若则汇编ENDIFIFIDNI,ADD AX,2;2忽略大小写时;若则汇编ENDIF,IFDIF,ADD AX,3;3 若则汇编ENDIFIFDIFI,ADD AX,4;4 忽略大小写时;若则汇编ENDIFENDM,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号