资源预览内容
第1页 / 共41页
第2页 / 共41页
第3页 / 共41页
第4页 / 共41页
第5页 / 共41页
第6页 / 共41页
第7页 / 共41页
第8页 / 共41页
第9页 / 共41页
第10页 / 共41页
第11页 / 共41页
第12页 / 共41页
第13页 / 共41页
第14页 / 共41页
第15页 / 共41页
第16页 / 共41页
第17页 / 共41页
第18页 / 共41页
第19页 / 共41页
第20页 / 共41页
亲,该文档总共41页,到这儿已超出免费预览范围,如果喜欢就下载吧!
点击查看更多>>
资源描述
单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单击此处编辑母版标题样式,第六章 子程序结构,6.1,子程序的设计方法,6.2,嵌套与递归子程序,6.3,子程序举例,6.1,子程序的设计方法,一、子程序指令,二、子程序的调用与返回,三、现场的保护与恢复,四、子程序参数的传递,一、子程序指令,子程序是完成特定功能的一段程序,当主程序(调用程序)需要执行这个功能时,采用,CALL,调用指令转移到该子程序的起始处执行,当运行完子程序功能后,采用,RET,返回指令回到主程序继续执行,一、子程序定义,定义子程序的一般格式如下:,子程序名,PROC NEAR|FAR,;,子程序体,子程序名,ENDP,对子程序定义的具体规定如下:,(1)“,子程序名”必须是一个合法的标识符,并前后二者要一致;,(2)PROC,和,ENDP,必须是成对出现的关键字,表示子程序定义开始和结束;,(3),子程序的类型有近,(NEAR),、远,(FAR),之分,其缺省的类型是近类型;,一、子程序定义,(4)NEAR,类型的子程序只能被与其同段的程序所调用,,FAR,类型的子程序可被不同段的程序所调用;,(5),子程序至少要有一条返回指令。返回指令是子程序的出口语句,但它不一定是子程序的最后一条语句;,(6),子程序名有三个属性:段值、偏移量和类型。其段值和偏移量对应于子程序的入口地址,其类型就是该子程序的类型。,一、子程序特点,重复性:,一个子程序只占一段存储区域,但可多次,调用它。,通用性:,子程序具有通用的功能。,可浮动性:,可以存放在存储区任何地址处。,可递归:,子程序可以调用其本身,一、子程序指令,调用指令,主程序调用子程序需要通过调用指令来实现的。主程序与子程序可以在同一个代码段中,此时调用称为,段内调用,;也可以在不同代码段中,此时称为,段间调用,。,直接调用:,子程序入口地址直接出现在调用指令中。,间接调用:,子程序入口地址存放在寄存器或者存储单元中,寄存器名称或存储单元地址出现在调用指令中,一、子程序指令,调用指令,CALL,指令分成4种类型(类似,JMP),段内直接调用,CALL label,或,NEAR PTR DST,段内间接调用,CALL,r16/m16,或,WORD PTR R16/M16,;,功能,:,(,1,),将子程序的返回地址存入栈,以便子程序返回时使用,SPSP2,SPIP,(,2,),转移到子程序入口地址执行子程序,例如:段内直接调用,CALL OPR,段内间接调用,CALL BX,CALL WORD PTR SI,一、子程序指令,调用指令,段间直接调用,CALL FAR PTR DEST,段间间接调用,CALL DWORD PTR DEST,功能,:,(,1,),将子程序的返回地址存入栈,以便子程序返回时使用。,SPSP2,SPCS,SPSP2,SPIP,(,2,)转移到子程序入口地址执行子程序,例如:段间直接调用,CALL FAR PTR DISP,段间间接调用,CALL DWORD PTR BX,CALL DWORD PTR ADDR,一、子程序指令,调用指令,调用指令功能,是暂停正在执行的程序,转去执行相应的子程序,由于子程序执行后还要返回主程序,所以转子之前还要记住,返回地址,(断点地址),即把返回地址送入栈保存。,段内调用,只把返回地址的偏移地址,(IP),入栈,段间调用,要把返回地址的偏移地址(,IP,)和段地址,(CS),都送入栈中。,一、子程序指令,返回指令,根据有无参数,分成2种类型,RET,;,无参数返回,RET i16,;,有参数返回,需要弹出,CALL,指令压入堆栈的返回地址,段内返回,出栈偏移地址,IP,IPSS:SP,SPSP2,段间返回,出栈偏移地址,IP,和段地址,CS,IPSS:SP,SPSP2,CSSS:SP,SPSP2,一、,子程序指令,返回指令,RET,的参数,RET i16,;,有参数返回,RET,指令可以带有一个立即数,i16,,则堆栈指针,SP,将增加,即,SPSP+i16,这个特点使得程序可以方便地废除若干执行,CALL,指令以前入栈的参数,一、子程序指令说明,在编写子程序时,除了要考虑实现子程序功能的方法,还要养成书写子程序说明信息的好习惯。,其说明信息一般包括以下几方面内容:,功能描述:,一、子程序指令说明,子程序名:,供调用子程序时使用,子程序功能:,供选子程序时参考。,入口和出口参数,:,说明子程序执行时具备条件和执行后的结果存放在何处。,所用寄存器,:最好采用寄存器的保护和恢复方法,子程序的所采用的算法,:,如果算法简单,可以不写,调用时的注意事项,:,尽量避免除入口参数外还有其它的要求,所用额外存储单元,:,可以减少为子程序定义自己的局部变量,二、子程序的调用与返回,CALL label,主程序,RET,子程序,回到,CALL,指令后的指令处返回地址,三、现场的保护与恢复,现场:,主程序转向子程序之前,其所使用的一些资源的状态(如标志位、,R/M,等),现场保护:,在子程序的功能实现前,把将要用到的寄存器中的原有的内容保存起来。,现场恢复:,子程序的功能实现后,将数据取出再送回原来的寄存器中,以保证子程序执行前后这些寄存器的内容不被改变,从而不影响主程序对这些寄存器的使用。,三、现场的保护与恢复,现场保护和现场恢复一般是通过栈来实现。,形式如下:,SUB1 PROC,PUSH AX POP DX,PUSH BX POP CX,PUSH CX POP BX,PUSH DX POP AX,RET,SUB1 ENDP,三、现场的保护与恢复,在主程序中进行,PUSH BX,PUSH AX,CALL SUB1,POP AX,POP BX,注意:,进栈/出栈的顺序,保护与恢复的对象:,主程序用到的存有数据、中间结果且在,CALL,指令后还要用到的,R/M,三、现场的保护与恢复,在子程序中进行,SUB1 PROC,PUSH BX,PUSH AX,POP AX,POP BX,RET,SUB1 ENDP,注意:,进栈/出栈的顺序,保护与恢复的对象:,子程序用到的,R/M,四、子程序参数的传递,入口参数,(输入参数):主程序提供给子程序,出口参数,(输出参数):子程序返回给主程序,参数的形式:,数据本身(传值),数据的地址(传址),传递的方法:,寄存器 堆栈 存储单元 变量,四、子程序参数的传递,寄存器传递参数,一方面,由于,CPU,中的寄存器在任何程序中都是“可见”的,一个程序对某寄存器赋值后,在另一个程序中就能直接使用,所以,用寄存器来传递参数最直接、简便,也是最常用的参数传递方式。,但另一方面,,CPU,中寄存器的个数和容量都是非常有限,所以,,该方法适用于传递较少的参数信息。,例,数据块的传递,四、子程序参数的传递,寄存器传递参数,;,功能描述:,实现数据块的搬家,从一个单元传递到另一个单元,;,入口参数:,源数据块的首地址、目的数据块的首地址和数据块的长度,使用三个寄存器,SI,,,DI,,,CX,作为参数传递。,;,出口参数:,无,,;,算法描述:,1,、定义一个源数据块的存储区域,一个目的数据,块区域。,;,2,、分别用,SI,和,DI,分别指向源和目的数据区域。,;,3,、每次移动,SI,和,DI,各一个单元,使其指向下一,个单元,一直到最后一个字符为止。,4,、完成从源数据到目的数据的传递赋值。,DATA SEGMENT,SOUCE DB 23H,45H,13H,2FH,1AH,94H,LENT EQU$-SOUCE,DEST DB LENT DUP(?),DATA ENDS,CODE SEGMENT,ASSUME CS:CODE,DS:DATA,START:MOV AX,DATA,MOV DS,AX,MOV SI,OFFSET SOUCE,MOV DI,OFFSET DEST,MOV CX,LENT,CALL MOVTOR,MOV AH,4CH,INT 21H,MOVTOR PROC NEAR,PUSH AX,LOP1:MOV AL,SI,MOV DI,AL,INC SI,INC DI,LOOP LOP1,POP AX,RET,MOVTOR ENDP,CODE ENDS,END START,例,6.3,十进制到十六进制数转换程序。要求从键盘取得一个十进制数,然后把该数以十六进制形式在屏幕上显示出来。,四、子程序参数的传递,寄存器传递参数,四、子程序参数的传递,栈传递参数,栈是一个特殊的数据结构,它通常是用来保存程序的返回地址。当用它来传递参数时,势必会造成数据和返回地址混合在一起的局面,用起来要特别仔细。,具体做法如下:,四、子程序参数的传递,栈传递参数,当用堆栈传递,入口参数,时,要在调用子程序前把有关参数依次压栈,子程序从堆栈中取到入口参数;,当用堆栈传递,出口参数,时,要在子程序返回前,把有关参数依次压栈,(,这里还需要做点额外操作,要保证返回地址一定在栈顶,),,调用程序就可以从堆栈中取到出口参数。,四、子程序参数的传递,栈传递参数,1,、用堆栈传递入口参数的调用方法:,PUSHPara1,PUSH,Paran,;,把,n,个字的参数压栈,CALLSUBPRO;,调用子程序,SUBPRO,Para,1,.,Para,n,返回地址,SP,SP,SP,SP,SP,2,、在子程序中取入口参数的方法,段内调用子程序,SUB1PROC NEAR,PUSHBP;,保护寄存器,BP,MOVBP,SP;,用寄存器,BP,来访问堆栈,读取参数,;,保护其它寄存器的指令,MOV,Paran,BP+4,MOVPara1,BP+4+2*(n-1),SUB1ENDP,返回地址,Para,n,.,Para,1,BP+4+2(n-1),BP+4,BP,SP,BP,四、子程序参数的传递,栈传递参数,例,数据块的传递,四、子程序参数的传递,栈传递参数,;,功能描述:,实现数据块的搬家,从一个单元传递到另一个单元,;,入口参数:,源数据块的首地址、目的数据块的首地址和数据块的长度,分别压入栈中来传递参数。,;,出口参数:,无,,;,算法描述:,1,、定义一个源数据块的存储区域,一个目的数据,块区域。,;,2,、把源数据块和目的数据块的首地址压入栈中传,递参数。,;,3,、从栈中弹出参数给,SI,和,DI,,每次把,SI,和,DI,分别移动一个单元,使其指向下一 个单元,一直到最后一个字符为止,完成参数传递。,DATA SEGMENT,SOUCE DB 23H,45H,13H,2FH,1AH,94H,LENT EQU$-SOUCE,DEST DB LENT DUP(?),DATA ENDS,CODE SEGMENT,ASSUME CS:CODE,DS:DATA,START:MOV AX,DATA,MOV DS,AX,MOV AX,OFFSET SOUCE,PUSH AX,MOV AX,OFFSET DEST,PUSH AX,MOV AX,LENT,PUSH AX,CALL MOVTOR,MOV AH,4CH,INT 21H,MOVTOR PROC NEAR,POP BX,POP CX,POP DI,POP SI,PUSH BX,LOP1:MOV AL,SI,MOV DI,AL,INC SI,INC DI,LOOP LOP1,RET,MOVTOR ENDP,CODE ENDS,END START,四、子程序参数的传递,存储单元传递参数,在调用子程序时,当需要向子程序传递大量数据时,因受到寄存器容量的限制,就不能采用寄存器传递参数的方式,而要改用约定存储单元的传送方式。,四、子程序参数的传递,存储单元传递参数,编写一个子程序分类统计出一个字符串中数字字符、字母和其它字符的个数。,该字符串的首地址用,DS:DX,来指定,(,以,0,为字符串结束,),,各类字符个数分别存放,BX,、,CX,和,DI,中。,;,功能描述,:分类统计出字符串中数字字符、字母和其它字符的个数,
点击显示更多内容>>

最新DOC

最新PPT

最新RAR

收藏 下载该资源
网站客服QQ:3392350380
装配图网版权所有
苏ICP备12009002号-6