Ch06 子程序与宏指令设计.ppt_第1页
Ch06 子程序与宏指令设计.ppt_第2页
Ch06 子程序与宏指令设计.ppt_第3页
Ch06 子程序与宏指令设计.ppt_第4页
Ch06 子程序与宏指令设计.ppt_第5页
已阅读5页,还剩124页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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 SEGMENT MAINPROC FAR CALLSUB1 RE

2、T MAINENDP SUB1PROC RET SUB1ENDP CODEENDS ENDMAIN,2调用程序和子程序在不同段的程序结构 (SUB2既被段间调用又被段内调用,必须是FAR属性。CALL要显式说明是FAR属性) CODE1SEGMENTMAINPROC FAR CALLFAR PTR SUB2 RET MAINENDP CODE1ENDS CODE2SEGMENT SUB1PROCFAR CALL FAR PTR SUB2 RET SUB1ENDP SUB2PROCFAR RET SUB2ENDP CODE2ENDS ENDMAIN,6.1.2 设计子程序时应注意的问题 1子程序

3、说明 2寄存器的保存与恢复 3密切注意堆栈状态,6.2 子程序参数传递,可以通过给子程序传递参数使其更通用。常用的参数传递方法如下:通过寄存器传递;若调用程序和子程序在同模块(源程序)中,子程序可以直接访问模块中的变量;通过地址表传递参数地址;通过堆栈传递参数或参数地址。,6.2.1 通过寄存器传递 这种传递方式使用方便,适用于参数较少的情况。 例1把BX中的16位二进制数转换成十进制并显示在屏幕上。,STASGSEGMENT DW 32 DUP(?) STASG ENDS CODE SEGMENT ASSUME CS:CODE MAIN PROC FAR MOV BX,162EH CALL

4、TERN MOV AX,4C00H INT 21H MAIN ENDP,程序6.3,TERN PROC;二十并显示。 MOV CX,10000 CALL DEC_DIV;转换万位数 MOV CX,1000 CALL DEC_DIV;转换千位数 MOV CX,100 CALL DEC_DIV;转换百位数 MOV CX,10 CALL DEC_DIV;转换十位数 MOV CX,1 CALL DEC_DIV;转换个位数 RET TERN ENDP,DEC_DIVPROC;CX中为十进制的位权 MOV AX,BX MOV DX,0 DIV CX;商为转换后的一位十进制数 MOV BX,DX MOV D

5、L,AL ADD DL,30H;转换成ASCII码 MOV AH,2;显示 INT 21H RET DEC_DIVENDP CODE ENDS END MAIN,6.2.2 同模块中的子程序可直接访问模块中的变量 若调用程序和子程序在同模块中,子程序可以直接访问模块中的变量。 例2实现数组求和功能。要求数组求和(不考虑溢出情况)由子程序实现,其数组元素及结果均为字型数据。见程序6.4。,STACKSGSEGMENT STACK STK DW 32 DUP(S) STACKSG ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW ($-A

6、RY)/2;数组元素个数 SUM DW ?;数组和的地址 DATA ENDS,程序6.4,CODE1 SEGMENT MAIN PROC FAR ASSUME CS:CODE1,DS:DATA PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX CALL FAR PTR ARY_SUM RET MAIN ENDP CODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2 ARY_SUM PROC FAR;数组求和子程序 PUSH AX;保存寄存器 PUSH CX PUSH SI LEA SI,ARY;取数组起始地址 MOV C

7、X,COUNT;取元素个数 XOR AX,AX;清0累加器,NEXT: ADD AX,SI;累加和 ADD SI,TYPE ARY;修改地址指针 LOOP NEXT MOV SUM,AX;存和 POP SI;恢复寄存器 POP CX POP AX RET ARY_SUM ENDP CODE2 ENDS END MAIN,6.2.3 通过地址表传递参数地址 适用于参数较多的情况。具体方法是先建立一个地址表,该表由参数地址构成。然后把表的首地址通过寄存器或堆栈传递给子程序。 例3编写一个数组求和子程序,其数组元素及结果均为字型数据。另定义两个数组,并编写一个主程序,通过调用数组求和子程序分别求出两

8、个数组的和。见程序6.5。,程序6.5,STACKSG SEGMENT STACK STK DW 32 DUP(S) STACKSG ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10;数组1 COUNT DW ($-ARY)/2;数组1的元素个数 SUM DW ?;数组1的和地址 NUM DW 10,20,30,40,50;数组2 CT DW ($-NUM)/2;数组2的元素个数 TOTAL DW ?;数组2的和地址 TABLE DW 3 DUP(?);地址表 DATA ENDS,CODE1SEGMENT MAINPROC FAR ASSUME CS:

9、CODE1,DS:DATA PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX;构造数组1的地址表 MOV TABLE,OFFSET ARY MOV 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

10、ARY_SUM ;段间调用调用数组求和子程序 RET MAIN ENDP CODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2 ARY_SUM PROC FAR;数组求和子程序 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 D

11、I;恢复寄存器 POP SI POP CX POP AX RET ARY_SUM ENDP CODE2 ENDS END MAIN,6.2.4 通过堆栈传递参数或参数地址 这种方式适用于参数较多,或子程序有多层嵌套、递归调用的情况。 步骤: 主程序把参数或参数地址压入堆栈; 子程序使用堆栈中的参数或通过栈中参数地址取到参数; 子程序返回时使用RET n指令调整SP指针,以便删除堆栈中已用过 的参数,保持堆栈平衡,保证程序的正确返回。,例4完成数组求和功能,求和由子程序实现,要求通过堆栈传递参数地址。 STACKSG SEGMENT STACK STK DW 16 DUP(?) STACKSG

12、ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW ($-ARY)/2 SUM DW ? DATA ENDS,程序6.6,CODE1 SEGMENT MAIN PROC FAR 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 ;调用求

13、和子程序 RET; MAIN ENDP CODE1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2 ARY_SUM PROC FAR;数组求和子程序 PUSH BP;保存BP值 MOV BP,SP;BP是堆栈数据的地址指针 PUSH 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

14、 NEXT MOV DI,AX;存和 POP DI;恢复寄存器内容 POP SI; POP CX; POP AX; POP BP; RET 6;返回并调整SP指针 ARY_SUM ENDP CODE2 ENDS END MAIN,返回,程序6.6中所有入栈操作对堆栈的影响,返回,程序6.6中主程序的RET执行前堆栈状态,例5完成数组求和功能,其中求和由子程序实现,要求使用结构访问堆栈中的参数。 编码见程序6.7。,返回,SS,SP,BP,程序6.7的堆栈及结构数据示意图,结构,程序6.7,STACKSG SEGMENT STACK STK DW 16 DUP(S) STACKSG ENDS D

15、ATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW ($-ARY)/2 SUM DW ? DATA ENDS,CODE1 SEGMENT MAIN PROC FAR 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 ENDP CODE

16、1 ENDS,CODE2 SEGMENT ASSUME CS:CODE2 STACK_STRC STRUC;定义结构 SAVE_BP DW ? SAVE_CS_IP DW 2 DUP(?) SUM_ADDR DW ? COUNT_ADDR DW ? ARY_ADDR DW ? STACK_STRC ENDS,ARY_SUMPROC FAR;数组求和子程序 PUSH BP;保存BP值 MOV BP,SP PUSH AX PUSH CX PUSH SI PUSH DI MOV SI,BP.ARY_ADDR;数组始地址 MOV DI,BP.COUNT_ADDR MOV CX,DI MOV DI,BP

17、.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 ENDP CODE2 ENDS END MAIN,子程序嵌套示意图,返回,6.3 嵌套与递归子程序,1.子程序嵌套,以下是求N!递归过程的描述。编码见程序6.8。,2.递归子程序,BEGINFACT(N,RESULT) SAVEREGISTER ON STACK IF N=0 RESULT1 ELS

18、E PUSH ADDRESS OF RESULT ONTO STACK PUSH N-1 ONTO STACK CALL FACT(N-1,RESULT) RESULTN*RESULT ENDIF RESTORE REGISTERS FROM STACK DELETE PARAMETERS FROM STACK,N!流程图,返回,程序6.8,STACKSG SEGMENTSTACK S ;定义堆栈 DW 128 DUP(ST) STACKSG ENDS DATA SEGMENT N_VAL DW3;定义N值 RESULT DW?;结果 DATA ENDS,CODE SEGMENT ASSUME

19、 CS:CODE,DS:DATA,SS:STACKSG FRAMESTRUC;定义帧结构 SAV_BPDW?;保存BP值 SAV_CS_IPDW 2 DUP(?);保存返回地址 NDW?;当前N值 RESULT_ADDRDW?;结果地址 FRAMEENDS,MAIN PROCFAR MOVAX,DATA MOVDS,AX LEABX,RESULT PUSHBX ;结果地址入栈 PUSHN_VAL ;N值入栈 CALLFARPTRFACT ;调用递归子程序 R1:MOVAX,4C00H INT21H MAIN ENDP,FACTPROC FAR;N!递归子程序 PUSH BP;保存BP值 MOV

20、 BP,SP;BP指向帧基地址 PUSH BX PUSH AX MOV BX,BP.RESULT_ADDR MOV 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 MOVAX,BX ;取中间结果(N1)! MULBP.N ;N*(N1)! JMPSHORT RETURN DONE: MOVAX,1 ;0!1 RETURN: MOVBX,AX ;存中间结果 POP AX PO

21、P BX POP BP RET 4 FACT ENDP CODE ENDS END MAIN,程序6.8的运行情况: 主程序把结果地址和N的初始值压入堆栈,然后调用FACT子程序。 在FACT中,它不断调用自身,每调用一次都要在堆栈中形成一帧,该帧由以下信息组成:子程序中要用到的寄存器内容、中间结果地址、(N1)的值、子程序返回地址,自身调用直到N0为止。,当N0时开始返回。 通过BP.RESULT_ADDR和BP.N取出堆栈中本次使用的参数,计算N*(N-1)!的值,保存中间结果,恢复寄存器的值,用RET 4返回并废除已用过的N和中间结果地址。 重复第步,逐层返回直到N等于初始值为止。,6.

22、4 宏 指 令,在高级汇编语言技术中,一段共用语句序列除了可以设计成子程序外,还可以设计成宏指令的形式。,6.4.1 宏定义、宏调用、宏扩展,宏指令是源程序中一段有独立功能的程序代码。宏指令由宏定义伪指令定义,它只需在源程序中定义一次,便可以多次被调用。,宏指令名 MACRO 形式参数表 ;宏指令体 ENDM,宏定义伪指令格式:,宏调用,宏指令一经定义,就可以在程序中调用它,这被称为宏调用。 宏调用格式:宏指令名 实参数表,宏扩展,宏扩展就是用宏定义体替换宏指令名,并用实参数替换形式参数。,例1输入一个字符的宏定义、宏调用、宏扩展,;宏定义 INCHARMACRO MOVAH,1 INT21H

23、;输入的字符在AL ENDM ;宏调用 INCHAR 当汇编程序汇编到宏指令INCHAR时,则对其扩展如下: 1 MOV AH,1 1 INT 21H,指令前的“1”表示该语句是扩展时替换得到的。,设计宏指令时应注意的问题,由于宏指令也像子程序那样可以被多次调用或被多个程序共享,所以在设计时需要注意以下问题: 1宏指令说明 2寄存器的保存与恢复 3宏指令中的符号说明,6.4.2 LOCAL伪指令,格式:LOCAL 局部符号表 功能:对局部符号表中的每个符号,在汇编时每扩展一次便建立一个惟一的符号,形如?xxxx(xxxx的值在0000FFFF之间)。以保证汇编时生成名字的惟一性。,例2以下是定

24、义一个延时程序的宏指令delay,并且在同一个程序中两次被调用的扩展情况。,;宏定义 DELAYMACRO LOCALLOP MOVCX,2801 LOP:LOOPLOP ENDM ,宏调用: DELAY DELAY 汇编时宏扩展如下: DELAY 0009 B9 0AF11 MOV CX,2801 000C E2 FE1 ?0000: LOOP ?0000 DELAY 000E B9 0AF11 MOV CX,2801 0011 E2 FE1 ?0001: LOOP ?0001,宏指令中参数的使用,在宏定义时可以带有形式参数,而在宏调用时给出实参数即可。 宏指令的参数可以是常数、寄存器、变量

25、、表达式、操作码或操作码的一部分、指令或伪指令助记符等。,例3定义在两个字型内存变量之间传送数据的宏指令,并调用它,然后观察其扩展情况。,MOVEMOCROX,Y PUSHAX MOVAX,X MOVY,AX POPAX ENDM,DATA SEGMENT VAR1 DW 6543H VAR2 DW ? DATA ENDS ;宏调用;宏扩展 MOVE VAR1,VAR2 1 PUSHAX 1 MOV AX,VAR1 1 MOV VAR2,AX 1 POP AX,6.4.3 宏指令嵌套,宏指令嵌套有两种情况: 宏定义体中含有宏调用; 宏定义体中含有宏定义。,DMACMACROMNAME,OPER

26、;外层宏定义 MNAMEMACRO X,Y,Z;内层宏定义 PUSH AX MOV AX,X OPER AX,Y MOV Z,AX POP AX ENDM ENDM,例4宏定义体中嵌套宏定义的宏指令、宏调用及宏扩展示例。,ADW25 BDW12 CDW? DMAC ADDITION,ADD;外层宏调用 1ADDITION MACRO X,Y,Z 1 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 P

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

28、内存中删除指定的宏指令。 例: PURGE INCHAR,6.4.4 宏操作符,这些操作符不仅适用于宏指令,也适用于重复汇编伪指令。 宏操作符格式名称 注释 宏注释,1操作符宏调用 PUTDATA0 MYDATA,5 ;宏扩展 1?0000MYDATA DB 5 ;宏调用 PUTDATA0 MYDATA,8 ;宏扩展 1?0001MYDATA DB 8,返回,由操作符括起的内容作为一个整体原样传递。 例如,可以使用符号包围目标,从而使该目标作为单 一的参数而不是多个参数的列表。 例6用不同的实参数调用PUTDATA宏指令,观察它们的变化。 PUTDATA MACRO THENAME,THEDA

29、TA PD_宏扩展 1 PD_MYDATA DB 5,2文本原样传递操作符,;宏调用2 PUTDATA MYDATA, ;宏扩展 1PD_MYDATA DB 5,4,3,又如以下符号定义语句: Numeric = 10+2 Textual equ 其汇编结果是: NUMERIC . . . . . . . .NUMBER 000C TEXTUAL . . . . . . . .TEXT 10+2 可以看到,对Numeric已经求值,而Textual只是一串字符而已。,返回,3字符原意操作符!,!操作符指示MASM把后跟的一个字符原样传送,即把它只作为普通字符对待。 例如,若你需要把“! 宏定义

30、 DEBUGMSG MACRO POINT,STRING MSG宏扩展 1MSG6 DB AT POINT 6:INSERTION FAILS!,4表达式操作符,在宏调用时,操作符强迫后跟的表达式立即求值,并把表达式的结果作为实参数替换,而不是表达式本身。 例8定义Problem1宏指令,并比较两次调用Problem1宏指令的区别,其中一次调用中使用了操作符。 Problem1宏指令功能:把由宏指令参数所指定的字型数组(array)的一个元素装入AX寄存器,该参数经汇编后必须是一个常数表达式。,PROBLEM1 MACRO PARAMETER MOV AX,ARRAYPARAMETER*2 E

31、NDM ;宏调用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在调用宏指令时对其中的参数经常是原文替换,所以有时产生的可能不是预期的结果。,考虑以下对PROBLEM1的宏调用及宏扩展: ;宏调用,要求装入ARRAY的元素2 PROBLEM1 2 ;宏扩展 1MOV AX,ARRAY2*2 可以看到,宏扩展后结果正确。,;宏调用:装入ARRAY

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

33、宏定义中,若注释以一个分号开始,则该注释在宏扩展时出现。但若注释以两个分号开始,则该注释在宏扩展时不出现。举例见列表伪指令。,返回,6.4.5 列表伪指令,格式 功能 .LALL 在列表文件中列出全部宏文本内容 (以双分号开头的注释除外) .SALL 在列表文件中不显示任何宏文本内容 .XALL (缺省)在列表文件中只列出可产生 目标代码的宏文本内容 注意:这些列表伪指令只影响列表文件,并不影响目标码的生成。,6.5 宏指令库,为了使宏指令能让多个程序共享,可以把它们组织到一个文件中,并存放在磁盘上,把这种文件称为宏指令库。 1.建立宏指令库 可以把一些常用的宏指令集中在一个文件中形成宏指令库

34、,用EDIT等任何文本编辑程序创建宏指令库,库名由用户自己起,而且对库的扩展名没有特殊要求。库中的宏指令以源代码形式出现。,假设MACRO.LIB中包含以下宏指令(详细内容见教材P174): SETMODE;设置8025彩色显示模式 INCHAR;接收一个字符,并返回在AL中 OUTCHAR X;输出X字符 PUSHREG ;保存寄存器DX、CX、BX、AX、DI、SI、BP POPREG ;恢复寄存器BP、SI、DI、AX、BX、CX、DX,WINDOW MACRO Collor,WleftTopRow,WLeftTopCul,WRightBottomRow,WRightBottomCul

35、;功能:开窗口 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 源文件名 功能:把另一个源文件包含到当前 源文件中。,3使用宏指令库中的宏指令 例9实现32位二进制数除以16位二进制数,并把结果用十进制数形式显示在

36、屏幕上。 编码见程序6.9。,程序6.9,INCLUDEMACRO.LIB PURGESETMODE,INCHAR,OUTCHAR, WINDOW,MOVE,MUL STACKSGSEGMENTSTACK S DW16DUP(?) STACKSGENDS DATASEGMENT ADD7006652;被除数 BDW1234;除数 CDW?;商 PROMPTDBThe result is: $ ASCIIDB5DUP(?),$;转换结果 DATAENDS,CODESEGMENT ASSUMECS:CODE,DS:DATA,SS:STACKSG MAINPROCFAR MOVAX,DATA MOV

37、DS,AX MOVDX,WORD PTR A+2 MOVAX,WORD PTR A DIVB,BIN_DECASCII,AX CLRSCRN DISPPROMPT DISPASCII RETURN MAINENDP CODEENDS ENDMAIN,4. 宏指令与子程序的区别,采用宏和子程序均能达到代码共享、简化源程序的目的,但它们的区别也是显而易见的。区别主要有以下几点:,(1) 工作方式的区别 (2) 参数传递的方便性 (3) 参数的多样性及灵活性,通常: 宏指令被用在代码较短且参数 较多的场合; 子程序被用在代码较长的场合。,6.6 重复伪指令,当程序中需要重复书写相同或几乎相同的语句时

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

39、ATA 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,10 REPT 2 DEC BX ENDM 汇编后产生如下语句: MOV BX,10 1DEC BX 1DEC BX,CHARSMACRONUM MOVAH,2 CHAR=A REPT NUM MOV DL,CHAR INT 21H CHAR=CHAR+1 ENDM ENDM,CODESEGMENT ASSUMECS:CODE MAINPROCFAR CHARS26 MOVAX,4C00H INT21H MAINENDP CODEENDS ENDMAIN 从本例可以看出,重复伪指令可以出现在宏指令中。,CHARSMACRONUM MO

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论