资源描述
*,第,9,章 子程序的设计,*,计算机科学与技术系,汇编语言程序设计,8086/8088,和,ARM,核汇编语言程序设计,第,9,章 子程序设计,11/28/2024,1,第,9,章 子程序的设计,9.2,子程序的参数传递,9.3,子程序嵌套与递归,第,9,章 子程序设计,9.1,子程序设计方法,9.4,子程序库,11/28/2024,2,第,9,章 子程序的设计,子程序又称为过程,是能完成特定功能有一定通用性的程序段,在需要时能被其它程序调用。调用子程序的程序常称为主程序。一般把源程序中反复出现的程序段或常用的功能独立的程序段设计成子程序供用户使用。,这样可以,简化源程序结构,、,节省目标程序的存储空间,,,提高程序设计的效率,。子程序结构也是模块化程序设计的基础。本章主要介绍子程序的,定义,、子程序,调用,和,返回,、子程序的,参数传递,以及,子程序库,等知识。,9.1,子程序设计方法,11/28/2024,3,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.1,子程序的定义,子程序的定义是由过程定义伪指令,PROC,和,ENDP,实现,格式如下:,过程名,PROC,NEAR|FAR,;过程体,过程名,ENDP,NEAR,属性的过程只能被相同代码段的其他程序调用,,FAR,属性的过程可以被不同代码段的程序调用。,(,1,),子程序和主程序,在同一个代码段,中,则子程序定义为,NEAR,属性。,(,2,),子程序和主程序,不在同一个代码段,中,则子程序定义为,FAR,属性。,(,3,),主程序,通常定义为,FAR,属性,这是因为主程序被看作,DOS,调用的一个子程序,以便执行完返回,DOS,。,11/28/2024,4,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.1,子程序的定义,MAIN PROC FAR,CALL SUBR1,RET,MAIN ENDP,;,SUBR1 PROC NEAR,RET,SUBR1 ENDP,MAIN PROC FAR,CALL SUBR1,RET,SUBR1 PROC NEAR,RET,SUBR1 ENDP,MAIN ENDP,段内定义,子程序可以放在代码段主程序开始执行之前的位置,也可放在代码段的末尾主程序执行终止后的位置。,P121,11/28/2024,5,第,9,章 子程序的设计,SEGX SEGMENT,SUBT PROC FAR,RET,SUBT ENDP,CALL SUBT,SEGX ENDS,;,SEGY SEGMENT,CALL SUBT,SEGY ENDS,9.1,子程序设计方法,9.1.1,子程序的定义,段间定义,11/28/2024,6,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.1,子程序的定义,为了便于其他程序员能正确使用子程序,在编写子程序时,还要养成书写子程序说明信息的良好习惯。子程序说明信息一般包括以下内容:,(,1,),子程序名,(,2,),功能描述,(,3,),入口和出口参数,(,4,),调用注意事项和说明等,11/28/2024,7,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.1,子程序的定义,例,9.1,编写一个子程序,从键盘输入一位十进制数。,;子程序名:,stdin,;功能:完成从键盘输入一位十进制数,;入口参数:等待键盘输入,;出口参数:,al,中存放输入的数值,stdin,proc,mov,ah,,,1,int,21h,cmp,al,,,30h,jl,next,cmp,al,,,39h,jg,next,and al,,,0fh,next,:,ret,stdin,endp,11/28/2024,8,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.2,子程序调用与返回,子程序调用与返回由,CALL,和,RET,指令实现。,子程序调用指令首先把,子程序的返回地址(即,CALL,指令的下一条指令的地址)压入堆栈,,然后,转移到子程序的入口地址执行子程序,。根据子程序和主程序是否在同一代码段,分为,段内调用,和,段间调用,。,子程序和主程序在同一个代码段中,称为,段内调用,;,子程序和主程序不在同一个代码段中,,称为,段间调用,。子程序返回指令负责把压入栈区的返回地址弹出送,IP,或,CSIP,,实现返回主程序继续往下执行。与子程序的段内调用和段间调用相对应,子程序的返回也分为段内返回和段间返回。,11/28/2024,9,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.2,子程序调用与返回,当子程序和主程序在同一个代码段中,子程序的定义和调用如下图,:,code segment,main proc far,call,suba,ret,main,endp,suba,proc near,ret,suba,endp,code ends,11/28/2024,10,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.2,子程序调用与返回,当子程序和主程序不在同一个代码段中,子程序的定义和调用如下图,:,code1 segment,main proc far,call far,ptr,suba,ret,main,endp,code1 ends,code2 segment,suba,proc far,ret,suba,endp,code2 ends,11/28/2024,11,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.3,寄存器内容的保护与恢复,通常主程序和子程序是分别编制的,所以它们可能会使用同一个寄存器。如果主程序中某个寄存器的内容在调用子程序后还要用,而子程序又恰好使用了同一个寄存器,当子程序修改了寄存器的内容后,返回到主程序时,该寄存器的内容也就不会是调用子程序前的内容,这样,常常会导致调用程序的出错。为此,编写子程序时,在一进入子程序后,就把它所用到的寄存器内容压进栈,在返回前,再把它们弹出栈。,为什么寄存器需要保护与恢复?,11/28/2024,12,第,9,章 子程序的设计,9.1,子程序设计方法,9.1.3,寄存器内容的保护与恢复,例如:若子程序,PROG,中改变了寄存器,AX,,,BX,,,CX,,,DX,的值,则,可采用如下方法保护和恢复现场。,PROGPROC,PUSHAX,PUSH BX,PUSHCX,;,保护现场,PUSHDX,POPDX,POPCX,POPBX,;,恢复现场,POPAX,RET,;,返回断点处,PROCENDP,注意,:,堆栈“先进后出”的操作特点,恢复寄存器的顺序不能搞错,。,11/28/2024,13,第,9,章 子程序的设计,9.2,子程序的参数传递,9.2.1,用寄存器传递参数,优点:,直接、简便,只要把参数存放在约定的寄存器中就行了。,缺点:,适用于传递参数较少的情况。,例,9.3,从键盘输入一组字符,直到“,0”,为止。编一子程序,完成当输入是小写字母时,则修改为大写字母。输入的字符存放在,string,为首址的存储单元中。,参数可以增加子程序的灵活性和通用性。调用程序传送给子程序的参数称为入口参数,子程序返回给调用程序的结果称为出口参数。,11/28/2024,14,第,9,章 子程序的设计,常用的,DOS,系统功能调用,1,单字符输入(,1,号调用),2,单字符显示(,2,号调用),3,打印输出(,5,号调用),4,结束调用(,4CH,号调用),5,显示字符串(,9,号调用),6,字符串输入(,10,号调用),11/28/2024,15,第,9,章 子程序的设计,1,单字符输入(,1,号调用),格式:,MOVAH,,,1,INT21H,功能:从键盘输入字符的,ASCII,码送入寄存器,AL,中,并送显示器显示。,2,单字符显示(,2,号调用),格式:,MOV DL,,,待显示字符的,ASCII,码,MOV AH,,,2,INT 21H,功能:将,DL,寄存器中的字符送显示器显示,.,11/28/2024,16,第,9,章 子程序的设计,3,打印输出(,5,号调用),格式,:,MOVDL,,,待打印字符的,ASCII,码,MOVAH,,,5,INT21H,功能:将,DL,寄存器中的字符送打印机打印。,4,结束调用(,4CH,号调用),格式:,MOVAH,,,4CH,INT21H,功能:终止当前程序并返回调用程序。,11/28/2024,17,第,9,章 子程序的设计,5,显示字符串(,9,号调用),格式:,LEADX,,,待显示字符串首偏移地址,MOVAH,,,9,INT21H,功能:将当前数据区中以结尾的字符串送显示器显示。,6,字符串输入(,10,号调用),格式:,LEADX,,,缓冲区首偏移地址,MOVAH,,,10,INT21H,功能:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示器显示。,maxlen,db 32,actlen,db?,string db 32 dup(?),lea,dx,maxlen,mov,ah,0ah,int,21h,说明:缓冲区的第一个字节保存最大字符数,这个最,大字符数由用户程序给出。如果键入的字符数,比此数大,机器发出嘟嘟声。第二个字节存放,实际输入的字节数,这个不是由用户填入的而,由功能,A,填入的。在这两个字节之后,才是我们,输入的字符串,。,11/28/2024,18,第,9,章 子程序的设计,;主程序,data segment,string db 100 dup(?),data ends,;-,code segment,assume,cs,:,code,,,ds,:,data,start,:,mov,ax,,,data,mov,ds,,,ax,mov,di,,,offset string,again,:,mov,ah,,,1,int,21h,cmp,al,0,je,exit,call,stob,mov,di,,,al,inc,di,jmp,again,exit,:,mov,ah,,,4ch,int,21h,;子程序名:,stob,;功能:将小写字母修改为大写字母,;入口参数:,al,存放输入的字符,;出口参数:,al,存放修改后的字符,stob,proc near,cmp,al,,,61h,jb,next,cmp,al,,,7ah,ja,next,sub al,,,20h,next,:,ret,stob,endp,code ends,end start,11/28/2024,19,第,9,章 子程序的设计,9.2,子程序的参数传递,9.2.2,用存储单元传递参数,这种方法是使用存储单元传递参数的,即主程序在存储单元建立一个参数表,存放子程序所要的参数,在主程序中将该参数表首地址传送给子程序,子程序通过参数表取得所需参数,并把结果也存放到指定存储单元中。,优点:,适合于传递参数较多的情况。,11/28/2024,20,第,9,章 子程序的设计,9.2,子程序的参数传递,9.2.2,用存储单元传递参数,例,9.4,使用存储单元传递参数的方法来实现例,9.3,。,;,主程序,datasegment,stringdb100 dup(?),Lent,dw,?,dataends,codesegment,assume,cs,:,code,,,ds,:,data,main proc far,start:,:,push,ds,mov,ax,,,0,push ax,mov,ax,,,data,mov,ds,,,ax,mov,cx,,,0,mov,di,,,offset string,again,:,mov,ah,,,1,int,21h,cmp,al,,,0,je,next,mov,di,,,al,inc,di,inc,cx,jmp,again,next,:,mov,lent,,,cx,lea,bx,,,string,callstob1,ret,11/28/2024,21,第,9,章 子程序的设计,9.2,子程序的参数传递,9.2.2,用存储单元传递参数,;子程序
展开阅读全文