




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、汇编语汇编语言程序设计设计高等高等教教育出版社育出版社v第第5 5章章 子程序设计子程序设计 如果程序中某段程序反复多次执行,且这段程序是连在一如果程序中某段程序反复多次执行,且这段程序是连在一起反复执行的,则可用循环程序结构来实现。但如果这样的程起反复执行的,则可用循环程序结构来实现。但如果这样的程序段是在程序的不同位置反复执行,则不能用循环程序结构,序段是在程序的不同位置反复执行,则不能用循环程序结构,此时有两种方法可提高编程效率,即采用子程序或宏。此时有两种方法可提高编程效率,即采用子程序或宏。汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.1 子程序与调用程序5.2 子程序与
2、主程序的参数传递5.3 子程序中寄存器的保护与恢复5.4 嵌套与递归子程序设计实训一 普通子程序设计实训二 嵌套子程序设计v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.1 5.1 子程序与调用程序子程序与调用程序 有关子程序的定义与调用方法在前面以做过介绍,子程序是一个有关子程序的定义与调用方法在前面以做过介绍,子程序是一个过程,它是由调用程序或主程序用过程,它是由调用程序或主程序用CALLCALL指令调用的。而子程序的返回指令调用的。而子程序的返回是由是由RETRET指令实现的。主程序与子程序的调用关系如下图所示。指令实现的。主程序与子程序
3、的调用关系如下图所示。主程序STAR:子程序SUB1PROCNEARCALLSUB1CALL SUB1RETSUB1ENDPENDv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.1.1 5.1.1 段内调用段内调用 供段内调用的子程序必须被定义为供段内调用的子程序必须被定义为NEARNEAR类型,并与主程序位类型,并与主程序位于同一个代码段中。子程序的位置通常在主程序的所有可执行指于同一个代码段中。子程序的位置通常在主程序的所有可执行指令之前或之后,不能放在主程序的可执行指令序列内部,否则会令之前或之后,不能放在主程序的可执行指令序列内部,否则
4、会破坏主程序结构。破坏主程序结构。【例【例5.1 5.1 】在以】在以STRGSTRG为首地址的缓冲区中存放着一个字符串,为首地址的缓冲区中存放着一个字符串,以以-1-1作为结束标志,编程统计字符串长度,并将结果存入作为结束标志,编程统计字符串长度,并将结果存入LENTHLENTH单元。要求统计字符串用子程序完成。单元。要求统计字符串用子程序完成。 分析:本题子程序的功能是统计字符串长度,只需要将被分析:本题子程序的功能是统计字符串长度,只需要将被统计字符串的首地址作为入口参数传递给子程序即可。统计的统计字符串的首地址作为入口参数传递给子程序即可。统计的结果放在某个寄存器如结果放在某个寄存器如
5、BXBX返回即可。程序如下:返回即可。程序如下:v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社DATADATASEGMENTSEGMENTSTRG DB HFEUWINFD4632STRG DB HFEUWINFD4632* *%587fdjljowjo#$4,-1%587fdjljowjo#$4,-1LENTH DWLENTH DW? ?DATADATAENDSENDSCODECODESEGMENTSEGMENTASSUME CS:CODE,DS:DATAASSUME CS:CODE,DS:DATASTART: MOVSTART: MOVAX,
6、DATAAX,DATAMOVMOVDS,AXDS,AXLEALEADX,STRG DX,STRG ;DXDX为字符串首地址,作入口参数为字符串首地址,作入口参数CALLCALLSCONTSCONT;调用子程序;调用子程序MOVMOVLENTH,BXLENTH,BX;保存结果;保存结果MOVMOVAH,4CHAH,4CHINTINT21H21Hv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社SCONTSCONT PROCPROCNEARNEARPUSHPUSHSISI;保护寄存器;保护寄存器XORXORBXBX,BXBX;DXDX寄存器用于统计结果寄
7、存器用于统计结果MOVMOVSI,DXSI,DX;传递地址指针;传递地址指针NEXT:NEXT: CMPCMPBYTE PTR SI,-1BYTE PTR SI,-1;是否结束标志;是否结束标志JZJZOVEROVER;是则转;是则转OVEROVERINCINCBXBX;统计;统计INCINCSISI;修改地址指针;修改地址指针JMPJMPNEXTNEXTOVER:OVER: POPPOPSISIRETRETSCONTSCONT ENDPENDPCODECODEENDSENDSENDENDSTARTSTARTv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社
8、育出版社5.1.25.1.2段间调用段间调用 供段间调用的子程序必须被定义为供段间调用的子程序必须被定义为FARFAR类型,并与主程序位类型,并与主程序位于不同的代码段中,也可分属于不同的模块。于不同的代码段中,也可分属于不同的模块。 【例【例5.2 5.2 】从键盘上输入一个长度小于】从键盘上输入一个长度小于100100的字符串,存入以的字符串,存入以BUFFBUFF为首地址的缓冲区,其中如有大写字母,要求用子程序转为首地址的缓冲区,其中如有大写字母,要求用子程序转换为小写字母,字符串以回车键作为结束。换为小写字母,字符串以回车键作为结束。 分析:本例中子程序以远程子程序的方式书写,它单独占
9、分析:本例中子程序以远程子程序的方式书写,它单独占用一个代码段。子程序的功能是将大写字母转换为小写字母,用一个代码段。子程序的功能是将大写字母转换为小写字母,方法是大写字母的方法是大写字母的ASCIIASCII码加上码加上20H20H。程序如下:。程序如下:v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社DATADATASEGMENTSEGMENTBUFFBUFFDBDB100 DUP(?)100 DUP(?)DATADATAENDSENDSCODE1CODE1SEGMENTSEGMENTASSUME CS:CODE1,DS:DATAASSUME
10、CS:CODE1,DS:DATASTART:START:MOVMOVAX,DATAAX,DATAMOVMOVDS,AXDS,AXLEALEASI,BUFFSI,BUFF;置地址指针;置地址指针NEXT:NEXT:MOVMOVAH,00HAH,00HINTINT16H16HCMPCMPAL,0DHAL,0DHJZJZDONEDONE;是回车键则结束;是回车键则结束CALLCALLFAR PTR CHANGFAR PTR CHANG;调用子程序;调用子程序MOVMOVSI,ALSI,AL;保存;保存INCINCSISI;修改地址指针;修改地址指针JMPJMPNEXTNEXTDONE:DONE:MO
11、VMOVAH,4CHAH,4CHINTINT21H21HCODE1CODE1ENDSENDSv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社CODE2CODE2SEGMENTSEGMENTASSUME CS:CODE2ASSUME CS:CODE2CHANGCHANGPROCPROCFARFARCMPCMPAL,AAL,AJBJBOVEROVERCMPCMPAL,ZAL,ZJAJAOVEROVERADDADDAL,20HAL,20H;是大写字母则转换为小写字母;是大写字母则转换为小写字母OVER:OVER:RETRETCHANGCHANGENDPE
12、NDPCODE2CODE2ENDSENDSENDENDSTARTSTART 程序中程序中CHANGCHANG子程序位于子程序位于CODE2CODE2段,而主程序位于段,而主程序位于CODE1CODE1段,段,ALAL寄存器既是入口参数,又是出口参数。寄存器既是入口参数,又是出口参数。v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社 注意:注意:子程序是利用调用(子程序是利用调用(CALLCALL)指令和返回()指令和返回(RETRET)指令来)指令来实现正确的调用和返回的。因为实现正确的调用和返回的。因为CALLCALL命令执行时压入堆栈的断点地命
13、令执行时压入堆栈的断点地址就是供子程序返回主程序时的地址(包括段地址和偏移地址),址就是供子程序返回主程序时的地址(包括段地址和偏移地址),编程时一定要注意子程序的类型属性,即是段内调用还是段间调用。编程时一定要注意子程序的类型属性,即是段内调用还是段间调用。段内调用和返回为段内调用和返回为NEARNEAR属性,段间调用和返回为属性,段间调用和返回为FARFAR属性。属性。8086/808086/808888的汇编程序用子程序定义的汇编程序用子程序定义PROCPROC的类型属性来确定的类型属性来确定CALLCALL和和RETRET指令指令的属性。如果所定义的子程序是的属性。如果所定义的子程序是
14、FARFAR属性,那么对它的调用和返回属性,那么对它的调用和返回一定都是一定都是FARFAR属性;如果所定义的子程序是属性;如果所定义的子程序是NEARNEAR属性,那么对它的属性,那么对它的调用和返回也一定是调用和返回也一定是NEARNEAR属性。这样用户只是在定义子程序时考虑属性。这样用户只是在定义子程序时考虑它的属性,而它的属性,而CALLCALL和和RETRET指令的属性就可以由汇编程序来确定了。指令的属性就可以由汇编程序来确定了。另外,进入子程序后再使用堆栈时也必须保证压入和弹出字节数一另外,进入子程序后再使用堆栈时也必须保证压入和弹出字节数一致,如果在这里堆栈存取出错,必然会导致返
15、回地址的错误。致,如果在这里堆栈存取出错,必然会导致返回地址的错误。v第第5 5章章 子程序设计子程序设计 返回本章首页返回本章首页汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.2 5.2 子程序与主程序的参数传递子程序与主程序的参数传递 主程序调用子程序时,通常会向子程序传递一些参数,称为入口主程序调用子程序时,通常会向子程序传递一些参数,称为入口参数,如例参数,如例5.15.1中的中的DXDX寄存器;子程序执行完毕返回主程序时也可能返寄存器;子程序执行完毕返回主程序时也可能返回一些结果,称为出口参数,如例回一些结果,称为出口参数,如例5.15.1中的中的BXBX。以上两种情况都
16、属于子。以上两种情况都属于子程序与主程序之间的参数传递。正确地进行参数传递,对于子程序设程序与主程序之间的参数传递。正确地进行参数传递,对于子程序设计是至关重要的。参数传递通常有三种方法:寄存器传递参数、存储计是至关重要的。参数传递通常有三种方法:寄存器传递参数、存储器传递参数和堆栈传递参数。下面分别举例说明。器传递参数和堆栈传递参数。下面分别举例说明。 v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.2.1 5.2.1 利用寄存器传递参数利用寄存器传递参数 使用寄存器传递参数最为快速直观,是最常用的参数传递方式。使用寄存器传递参数最为快速直观
17、,是最常用的参数传递方式。但由于寄存器是计算机中的稀有资源,数目有限,因而只适于传递较但由于寄存器是计算机中的稀有资源,数目有限,因而只适于传递较少数目的参数。其方法是主程序将子程序的入口参数放入指定的寄存少数目的参数。其方法是主程序将子程序的入口参数放入指定的寄存器,然后再调用子程序。器,然后再调用子程序。 v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社【例【例5.2 5.2 】现有以现有以DATDAT为首地址的字数组共为首地址的字数组共1010个元素,编程按个元素,编程按5 5位十位十进制形式显示这进制形式显示这1010个元素,并注明正负号。
18、要求比较正负及显示部个元素,并注明正负号。要求比较正负及显示部分用子程序实现。分用子程序实现。分析:本题主程序功能相对比较简单,只需用循环程序调用子程序分析:本题主程序功能相对比较简单,只需用循环程序调用子程序即可完成即可完成1010个数的显示。子程序主要完成三项工作:个数的显示。子程序主要完成三项工作:(1)(1)判断数据的正负并在数据为负数时显示负号;判断数据的正负并在数据为负数时显示负号;(2)(2)十六进制数转换为十进制数;十六进制数转换为十进制数;(3)(3)十进制数的显示。十进制数的显示。v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社
19、DATADATASEGMENTSEGMENTDAT DAT DW 1234HDW 1234H,0FFFFH0FFFFH,7FFFH7FFFH,1000H1000H,1001H1001H DW -123DW -123,123123, -0FFFH-0FFFH,0FFFH0FFFH,0FFH0FFHMSGMSGDB Display end.$DB Display end.$WRMSGWRMSGDB Display wrong.$DB Display wrong.$DECIMLDECIML DB 5 DUP(0)DB 5 DUP(0),0AH0AH,0DH0DH,$DATADATAENDSENDSC
20、ODE CODE SEGMENTSEGMENTASSUME CS:CODEASSUME CS:CODE,DS:DATADS:DATASTART:START: MOV AXMOV AX,DATADATA MOV DSMOV DS,AXAX MOV CX MOV CX,1010;数据个数为;数据个数为1010 LEA DI LEA DI,DATDAT;置地址指针;置地址指针v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社NEXT: NEXT: MOV BXMOV BX,DIDI;置入口参数,每次调用传递一个参数;置入口参数,每次调用传递一个参数 CAL
21、L DISPCALL DISP INC DI INC DI INC INC DIDI;修改地址指针;修改地址指针 LOOP NEXTLOOP NEXT CMP DXCMP DX,OKOK JNE WRONGJNE WRONG;1010个数未正确显示转个数未正确显示转WRONGWRONG LEA LEA DXDX,MSGMSG JMP MDISPJMP MDISPWRONG:WRONG: LEA DXLEA DX,WRMSGWRMSGMDISP: MDISP: MOV MOV AHAH,09H09H INT 21HINT 21H;显示信息;显示信息 MOV MOV AHAH,4CH4CH INT
22、 21HINT 21Hv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社;DISPDISP子程序功能:以十进制形式显示子程序功能:以十进制形式显示BXBX寄存器中的有符号数;寄存器中的有符号数; ;十六进制数转换为十进制采用除;十六进制数转换为十进制采用除1010取余的方法;取余的方法;入口参数:;入口参数:BXBX;出口参数:;出口参数:DX=OKDX=OK表示正常显示,否则表示未正常显示完。表示正常显示,否则表示未正常显示完。DISP DISP PROC PROC NEARNEAR PUSH PUSH DIDIPUSHPUSHAXAX PUSH
23、CXPUSH CX PUSH DXPUSH DX;保护寄存器;保护寄存器 MOV MOV DIDI,CX CX CMP BXCMP BX,0 0;BXBX为入口参数为入口参数 JGE NEXT1JGE NEXT1;是正数转;是正数转NEXT1NEXT1 MOV DLMOV DL,- MOV AHMOV AH,2 2 INT 21HINT 21H;显示负号;显示负号 NEG BXNEG BX;转为正数;转为正数v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社NEXT1: NEXT1: LEA LEA SISI,DECIML+4DECIML+4 MOV
24、 MOV AXAX,BXBX MOV CXMOV CX,1010AGAIN: AGAIN: XOR XOR DXDX,DXDX IDIV IDIV CX CX ADD DLADD DL,30H30H MOV MOV SISI,DLDL DEC DEC SISI JGE JGE AGAINAGAIN;转换为十进制数并以;转换为十进制数并以ASCIIASCII码存储码存储 LEA LEA DXDX,DECIMLDECIML MOV MOV AHAH,09H09H INT INT 21H21H;显示;显示 CMP CMP DIDI,1 1 JNZ JNZ GOGO;1010个数未显示完转个数未显示完
25、转GOGO MOV MOV DXDX,OKOKGO: GO: POP POP DXDX POP CXPOP CX POP AXPOP AX POP DIPOP DI RETRETDISPDISPENDPENDPCODE CODE ENDSENDS END END START STARTv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.2.25.2.2利用存储单元传递参数利用存储单元传递参数 当主程序向子程序传递的参数较多时,例如超过当主程序向子程序传递的参数较多时,例如超过1010个,则很难个,则很难用寄存器传递参数,此时可用约定的存储单元传递参
26、数。方法是主用寄存器传递参数,此时可用约定的存储单元传递参数。方法是主程序将要传递给子程序的数据存入存储单元,在调用子程序时只需程序将要传递给子程序的数据存入存储单元,在调用子程序时只需要将这些数据的首地址告诉子程序即可。要将这些数据的首地址告诉子程序即可。 【例【例5.4 5.4 】在以在以MSG0MSG0和和MSG1MSG1为首地址的字缓冲区中分别存有一批为首地址的字缓冲区中分别存有一批数据,且都以数据,且都以“#”#”作为结束,编程分别找出其最小值,结果存入作为结束,编程分别找出其最小值,结果存入RSRSLTLT和和RSLT+1RSLT+1单元。要求用子程序实现找最小值。单元。要求用子程
27、序实现找最小值。 分析:本题数据个数是未知数,不能一次将所有数据通过寄存分析:本题数据个数是未知数,不能一次将所有数据通过寄存器传给子程序,但可以将数据的首地址作为参数分别传送给子程序。器传给子程序,但可以将数据的首地址作为参数分别传送给子程序。程序如下:程序如下:v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社DATADATASEGMENTSEGMENTMSG0MSG0DWDW123123,1ABH1ABH,9BCDH9BCDH,0A99H0A99H,1010,1234H1234H,1A1BH1A1BH,#MSG1MSG1DWDW1212,567
28、8H5678H,0FFCCH0FFCCH,9876H9876H,78H78H,0F8H0F8H,#RSLTRSLTDWDW?,?,?DATADATAENDSENDSCODECODESEGMENTSEGMENTASSUME CS:CODEASSUME CS:CODE,DS:DATADS:DATASMALSMALPROCPROCNEARNEARNEXT:NEXT:CMPCMPWORD PTRSIWORD PTRSI,#;SISI为入口参数为入口参数JZJZOVEROVERCMPCMPAXAX,SISIJLEJLEGOONGOON;AXAX小于或等于下一个数则转小于或等于下一个数则转GOONGOON
29、MOVMOVAXAX,SISI;否则将小值赋给;否则将小值赋给AXAX(出口参数)(出口参数)v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社GOON:GOON:ADDADDSISI,2 2JMPJMPNEXTNEXT;循环;循环OVEROVER: RETRETSMALSMALENDPENDPSTART:START: MOVMOVAXAX,DATADATAMOVMOVDSDS,AXAXLEALEASISI,MSG0MSG0;SISI做地址指针做地址指针CALLCALLSMALSMALMOVMOVRSLTRSLT,AXAX;保存第一个结果;保存第一个
30、结果LEALEASISI,MSG1MSG1CALLCALLSMALSMALMOVMOVRSLT+2RSLT+2,AXAX;保存第二个结果;保存第二个结果MOVMOVAHAH,4CH4CHINTINT21H21HCODECODEENDSENDSENDENDSTARTSTARTv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.2.35.2.3利用堆栈传递参数利用堆栈传递参数 子程序入口和出口参数较少时,可用寄存器传递参数;而参数较子程序入口和出口参数较少时,可用寄存器传递参数;而参数较多时,一种方法是利用存储单元传递参数,还有一种方法就是利用堆多时,
31、一种方法是利用存储单元传递参数,还有一种方法就是利用堆栈传递参数。具体方法如下:栈传递参数。具体方法如下: 1. 1.入口参数传递入口参数传递 主程序将参数依次入栈,然后调用子程序,子程序从堆栈中读取主程序将参数依次入栈,然后调用子程序,子程序从堆栈中读取参数。参数。 2. 2.出口参数传递出口参数传递 子程序返回前,先恢复所保存寄存器的内容,并将堆栈中保存的子程序返回前,先恢复所保存寄存器的内容,并将堆栈中保存的返回地址出栈保存,再将出口参数入栈,最后将返回地址入栈,以保返回地址出栈保存,再将出口参数入栈,最后将返回地址入栈,以保证其位于栈顶,这样可正常返回主程序。这个过程显得比较麻烦,故证
32、其位于栈顶,这样可正常返回主程序。这个过程显得比较麻烦,故一般使用寄存器或存储单元传递出口参数。以下主要分析入口参数传一般使用寄存器或存储单元传递出口参数。以下主要分析入口参数传递方法。递方法。v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社(1 1)主程序中向子程序传递入口参数)主程序中向子程序传递入口参数PUSHPUSHPARA1PARA1PUSHPUSHPARA2PARA2PUSHPUSHPARANPARAN ;N N个参数入栈,参数得数值类型为字类型个参数入栈,参数得数值类型为字类型CALLCALLSUBNAMESUBNAMEv第第5 5章
33、章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社(2 2)子程序中取入口参数的方法)子程序中取入口参数的方法 进入子程序后,由于位于栈顶的是返回地址,因此不能直接将进入子程序后,由于位于栈顶的是返回地址,因此不能直接将N N个参数出栈。故可将返回地址保存,再将参数出栈,最后将返回地址个参数出栈。故可将返回地址保存,再将参数出栈,最后将返回地址重新入栈。但通常的做法是用基址寄存器重新入栈。但通常的做法是用基址寄存器BPBP直接访问堆栈中的参数。直接访问堆栈中的参数。根据段内调用子程序与段间调用子程序的不同,访问方式略有差别。根据段内调用子程序与段间调用子程序的不同
34、,访问方式略有差别。对于段内调用,对于段内调用,CALLCALL指令仅把指令指针寄存器指令仅把指令指针寄存器IPIP的内容入栈,子程序的内容入栈,子程序刚被执行时,堆栈情况如图刚被执行时,堆栈情况如图5-2(a)5-2(a)所示。所示。v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社PARANPARAN返回地址返回地址PARA1PARA1PARA2PARA2SPSP(a) (a) 子程序刚被执行时的堆栈情况子程序刚被执行时的堆栈情况 图图5-2 5-2 子程序段内调用时的堆栈情况子程序段内调用时的堆栈情况v第第5 5章章 子程序设计子程序设计 汇编
35、语汇编语言程序设计设计高等高等教教育出版社育出版社SUBNAMESUBNAMEPROCPROCNEARNEARPUSHPUSHBPBP;保护;保护BPBPMOVMOVBPBP,SPSPPUSHPUSHREG1REG1;保护寄存器;保护寄存器REG1REG1PUSHPUSHREG2REG2;保护寄存器;保护寄存器REG2REG2POPPOPREG1REG1;恢复寄存器;恢复寄存器SUBNAMESUBNAMEENDPENDP此时堆栈情况如图此时堆栈情况如图5-2(b)5-2(b)所示。所示。 子程序子程序BPBP访问堆栈前,通常将访问堆栈前,通常将BPBP入栈以保存入栈以保存BPBP的内容,再将当
36、的内容,再将当前前SPSP的值传送给的值传送给BPBP,然后保护其它寄存器信息。过程如下:,然后保护其它寄存器信息。过程如下:v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社PARANPARAN返回地址返回地址PARA1PARA1PARA2PARA2BPBP其它信息其它信息SPSPBP+2BP+2BP+4BP+4BPBP(b)(b)子程序保护完其它信息后的堆栈情况子程序保护完其它信息后的堆栈情况 图图5-2 5-2 子程序段内调用时的堆栈情况子程序段内调用时的堆栈情况v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出
37、版社育出版社 由图由图5-2(b)5-2(b)可以看出,当前的可以看出,当前的BPBP值与最后入栈的参数值与最后入栈的参数PARANPARAN之间之间隔着被保护的原隔着被保护的原BPBP值和返回地址,由于它们分别占用了两个字节的存值和返回地址,由于它们分别占用了两个字节的存储单元,故当前的储单元,故当前的BPBP值所指向的单元与值所指向的单元与PARANPARAN相距相距4 4个字节。所以个字节。所以PARAPARAN N的偏移地址为的偏移地址为BP+4BP+4,第,第I I个参数个参数PARAIPARAI的偏移地址为的偏移地址为BP+4+2BP+4+2* *(N-(N-I)I),所以可以通过
38、下面的指令来访问第,所以可以通过下面的指令来访问第I I个参数个参数: :MOVMOVAXAX,BP+4+2BP+4+2* *(N-I)(N-I) 当子程序的调用为段间调用时,返回地址由偏移地址当子程序的调用为段间调用时,返回地址由偏移地址IPIP和段地址和段地址CSCS共同构成,故在共同构成,故在BPBP与与PARANPARAN之间隔着之间隔着6 6个字节,此时个字节,此时PARANPARAN的偏移地的偏移地址为址为BP+6BP+6,而,而PARAIPARAI的偏移地址为的偏移地址为BP+4+2BP+4+2* *(N-I)(N-I),所以可以通过,所以可以通过下面的指令来访问第下面的指令来访
39、问第I I个参数个参数: :MOVMOVAXAX,BP+6+2BP+6+2* *(N-I)(N-I)v第第5 5章章 子程序设计子程序设计 返回本章首页返回本章首页汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.3 5.3 子程序中寄存器的保护与恢复子程序中寄存器的保护与恢复 计算机中的寄存器个数是有限的,主程序在调用子程序之计算机中的寄存器个数是有限的,主程序在调用子程序之前,如果已经使用了若干寄存器,而且这些寄存器中保存的数前,如果已经使用了若干寄存器,而且这些寄存器中保存的数据后面还要用到,那么这些寄存器的内容就不能被修改。而子据后面还要用到,那么这些寄存器的内容就不能被修改。
40、而子程序如果也必须使用这些寄存器,则必定会修改这些寄存器的程序如果也必须使用这些寄存器,则必定会修改这些寄存器的内容。这样会使程序出错。但如果在子程序中对这些寄存器予内容。这样会使程序出错。但如果在子程序中对这些寄存器予以保护和恢复,则可以避免这种错误。需要保护的寄存器主要以保护和恢复,则可以避免这种错误。需要保护的寄存器主要满足下面两个条件:满足下面两个条件: (1) (1)其中存放着主程序后面还要用到的内容其中存放着主程序后面还要用到的内容 (2) (2)子程序要改变其中的内容子程序要改变其中的内容v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版
41、社 编程时要注意,作为出口参数的寄存器不能是需要保护的编程时要注意,作为出口参数的寄存器不能是需要保护的寄存器。上述寄存器的保护是针对与某一个主程序的,当子寄存器。上述寄存器的保护是针对与某一个主程序的,当子程序是一个公用子程序时,事先并不知道需要保护哪些寄存程序是一个公用子程序时,事先并不知道需要保护哪些寄存器,所以通常的做法是将子程序所用到的除作为出口参数的器,所以通常的做法是将子程序所用到的除作为出口参数的寄存器之外的所有寄存器全部保护与恢复,具体方法是:在寄存器之外的所有寄存器全部保护与恢复,具体方法是:在子程序的开始将所有寄存器依次入栈,返回主程序之前再以子程序的开始将所有寄存器依次
42、入栈,返回主程序之前再以相反顺序出栈。用指令描述如下:相反顺序出栈。用指令描述如下:v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社SUBNAMESUBNAMEPROCPROCPUSHPUSHREG1REG1PUSHPUSHREG2REG2PUSHPUSHREGNREGNPOPPOPREGNREGNPOPPOPREG2REG2POPPOPREG1REG1RETRETSUBNAMESUBNAMEENDPENDPv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社 以上是寄存器保护与恢复的一般形式,在程序设计中
43、可以上是寄存器保护与恢复的一般形式,在程序设计中可根据实际情况进行安排,但后进先出的次序不能改动。根据实际情况进行安排,但后进先出的次序不能改动。 一般来说子程序是要反复使用或提供用户使用,所以编一般来说子程序是要反复使用或提供用户使用,所以编写子程序时应尽量采用较好的算法,使子程序运行速度比较写子程序时应尽量采用较好的算法,使子程序运行速度比较快,又节省内存。同时还应最大限度地满足今后程序维护与快,又节省内存。同时还应最大限度地满足今后程序维护与使用的需要。在设计子程序的同时就应当建立相应的说明文使用的需要。在设计子程序的同时就应当建立相应的说明文档,清楚地描述子程序的功能和调用方法,通常子
44、程序说明档,清楚地描述子程序的功能和调用方法,通常子程序说明文档应包括文档应包括: :子程序名称、子程序功能、入口参数、出口参数、子程序名称、子程序功能、入口参数、出口参数、工作寄存器、工作单元及最后修改日期等。工作寄存器、工作单元及最后修改日期等。v第第5 5章章 子程序设计子程序设计 返回本章首页返回本章首页汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.4 5.4 嵌套与递归子程序设计嵌套与递归子程序设计 5.4.1 5.4.1 子程序嵌套子程序嵌套 通常,主程序可以调用子程序。同样,一个子程序也可以作为通常,主程序可以调用子程序。同样,一个子程序也可以作为调用程序去调用另一个
45、子程序,这种情况称为子程序的嵌套。嵌套调用程序去调用另一个子程序,这种情况称为子程序的嵌套。嵌套的层次不限,其层数称为嵌套深度。图的层次不限,其层数称为嵌套深度。图5-35-3表示了嵌套深度为表示了嵌套深度为2 2时的时的子程序嵌套情况。子程序嵌套情况。主程序主程序 子程序子程序A A 子程序子程序B B PROC_A PROC_B PROC_A PROC_B CALL PROC_A CALL PROC_A CALL PROC_B CALL PROC_B RET RET RET RETv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社 嵌套子程序的设
46、计并没有什么特殊要求,除子程序的调嵌套子程序的设计并没有什么特殊要求,除子程序的调用和返回应正确使用用和返回应正确使用CALLCALL和和RETRET指令外,要注意寄存器的保指令外,要注意寄存器的保存和恢复,以避免发生各层次子程序之间因寄存器冲突而出存和恢复,以避免发生各层次子程序之间因寄存器冲突而出错的情况。如果程序中使用了堆栈,例如使用堆栈来传送参错的情况。如果程序中使用了堆栈,例如使用堆栈来传送参数等,则对堆栈的操作要格外小心,避免发生因堆栈使用中数等,则对堆栈的操作要格外小心,避免发生因堆栈使用中的问题而造成子程序不能正确返回的错误。的问题而造成子程序不能正确返回的错误。v第第5 5章
47、章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社 【例【例5.55.5】在在BUFBUF开始的开始的2020个字节存储单元中存放着十六进个字节存储单元中存放着十六进制数据(每个单元由制数据(每个单元由2 2位十六进制数组成)。编程把每位十六进位十六进制数组成)。编程把每位十六进制数据转换为相应的制数据转换为相应的ASCIIASCII码,结果存入码,结果存入DATDAT开始的各单元中。开始的各单元中。 分析:由于每个单元由分析:由于每个单元由2 2位十六进制数组成,因此,位十六进制数组成,因此,2020个单个单元共有元共有4040位十六进制数据。下面使用嵌套子程序
48、完成编程。用位十六进制数据。下面使用嵌套子程序完成编程。用二级子程序二级子程序HTOAHTOA完成十六进制数据到完成十六进制数据到ASCIIASCII码的转换。一级子程码的转换。一级子程序序CHANGCHANG完成每单元十六进制数据的分离,并调用完成每单元十六进制数据的分离,并调用 HTOA HTOA完成转完成转换工作。程序如下:换工作。程序如下: v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社DATADATASEGMENTSEGMENTBUFBUFDBDB12H12H,34H34H,56H56H,78H78H,9AH9AH,0BCH0BCH,0
49、DEH0DEH,0FFH0FFH,00H00H,1AH1AHDBDB58H58H,6AH6AH,67H67H,78H78H,9AH9AH,0BCH0BCH,0DEH0DEH,0FFH0FFH,55H55H,88H88HDATDATDBDB4040DUP(?)DUP(?)DATADATAENDSENDSCODECODESEGMENTSEGMENTASSUMEASSUMECS:CODECS:CODE,DS:DATADS:DATASTART:START:MOVMOVAXAX,DATADATAMOVMOVDSDS,AXAXLEALEASISI,BUFBUF;1616进制数据地址指针进制数据地址指针LE
50、ALEADIDI,DATDAT;ASCIIASCII码地址指针码地址指针MOVMOVCXCX,2020;计数器初值;计数器初值NEXT:NEXT:MOVMOVALAL,SISI;取;取1616进制数据进制数据CALLCALLCHANGCHANG;调用子程序转换;调用子程序转换INCINCSISI;修改地址指针;修改地址指针INCINCDIDI;修改地址指针;修改地址指针LOOPLOOPNEXTNEXT;未转换完,循环;未转换完,循环MOVMOVAHAH,4CH4CHINTINT21H21Hv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社;子程序名:
51、;子程序名:CHANGCHANG;入口参数:;入口参数:ALAL中存放中存放2 2位十六进制数,位十六进制数,DIDI为为ASCIIASCII码存放地址码存放地址;出口参数:转换结果存在;出口参数:转换结果存在DATDAT开始的缓冲区开始的缓冲区CHANGCHANGPROCPROCNEARNEARMOVMOVBLBL,ALAL;数据存至;数据存至BLBLMOVMOVCLCL,4 4;取高;取高4 4位位SHRSHRALAL,CLCLCALLCALLHTOAHTOA;转换为;转换为ASCIIASCII码码MOVMOVDIDI,ALAL;保存;保存INCINCDIDI;修改地址指针;修改地址指针M
52、OVMOVALAL,BLBL;取低;取低4 4位数据位数据ANDANDALAL,0F0H0F0H;取低;取低4 4位数据位数据CALLCALLHTOAHTOA;转换为;转换为ASCIIASCII码码MOVMOVDIDI,ALAL;保存;保存RETRETCHANGCHANGENDPENDPv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社;子程序名:;子程序名:HTOAHTOA;入口参数:;入口参数:ALAL中低中低4 4位为待转换的位为待转换的1 1位十六进制数据位十六进制数据;出口参数:;出口参数:ALAL中为转换后的中为转换后的ASCIIASCI
53、I码码HTOAHTOAPROCPROCNEARNEARCMPCMPALAL,10H10HJBJBASCDASCDADDADDALAL,07H07H;字母预加;字母预加07H07HASCD:ASCD:ADDADDALAL,30H30H;数字加;数字加30H30HRETRETHTOAHTOAENDPENDPCODECODEENDSENDSENDENDSTARTSTARTv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社5.4.2 5.4.2 递归子程序设计递归子程序设计 当子程序直接或间接地嵌套调用自身时称为递归调用,当子程序直接或间接地嵌套调用自身时称
54、为递归调用,含有递归调用的子程序称为递归子程序。含有递归调用的子程序称为递归子程序。 递归子程序必须采用寄存器或堆栈传递参数,递归深递归子程序必须采用寄存器或堆栈传递参数,递归深度受堆栈空间的限制。度受堆栈空间的限制。 进行递归调用时需注意的是,一个递归程序必须有一进行递归调用时需注意的是,一个递归程序必须有一个能够退出递归调用的测试语句。也就是说,递归调用是个能够退出递归调用的测试语句。也就是说,递归调用是有条件的,满足了条件后,才可以进行递归调用;如果无有条件的,满足了条件后,才可以进行递归调用;如果无条件地进行递归调用,那么会使堆栈空间溢出,导致严重条件地进行递归调用,那么会使堆栈空间溢
55、出,导致严重的错误。的错误。v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社【例例5.65.6】 编程完成求编程完成求N!N!分析:根据阶乘的定义分析:根据阶乘的定义 1 1n n!= = n n* *(n-1n-1)!)! 这是一个递归定义式,可采用子程序的的递归调用形式。程序如下:这是一个递归定义式,可采用子程序的的递归调用形式。程序如下:v第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社DATADATASEGMENTSEGMENTNUMNUMDB 5DB 5;设数据为;设数据为5 5RESULTRE
56、SULT DW DW ?DATADATAENDSENDSSTACKSTACKSEGMENTSEGMENTDB DB 100 DUP100 DUP(?)(?)STACKSTACKENDSENDSCODECODESEGMENTSEGMENTASSUMEASSUME CSCS:CODECODE,DSDS:DATADATA,SSSS:STACKSTACKSTARTSTART:MOVMOVAXAX,DATADATAMOVMOVDSDS,AXAXMOVMOVAHAH,0 0MOVMOVALAL,NUMNUM;取数据;取数据CALLCALLFACTFACT;调用子程序;调用子程序MOVMOVRESULTRE
57、SULT,DXDX;保存结果;保存结果MOVMOVAHAH,4CH4CHINTINT21H21Hv第第5 5章章 子程序设计子程序设计 汇编语汇编语言程序设计设计高等高等教教育出版社育出版社;子程序名:;子程序名:FACTFACT;入口参数:;入口参数:AL=5AL=5;出口参数:;出口参数:DX= 5!DX= 5!FACTFACTPROCPROCNEARNEARCMPCMPAXAX,0 0JNZJNZNEXTNEXT;数据为不为;数据为不为0 0,转,转NEXTNEXTMOVMOVDLDL,1 1;否则,返回;否则,返回RETRETNEXTNEXT:PUSHPUSHAXAX;对应数据入栈;对
58、应数据入栈DECDECALALCALLCALLFACTFACTBACKBACK:POPPOPCXCX;弹出至;弹出至CXCXXORXORAXAX,AXAXMULT:MULT:ADDADDALAL,DLDLLOOPLOOPMULTMULTMOVMOVDXDX,AXAXRETRETFACTFACTENDPENDPCODECODEENDSENDSENDENDSTARTSTARTv第第5 5章章 子程序设计子程序设计 返回本章首页返回本章首页汇编语汇编语言程序设计设计高等高等教教育出版社育出版社本章小结本章小结 子程序技术是一种解决重复性问题的重要设计方法,采用子程序结子程序技术是一种解决重复性问题的
59、重要设计方法,采用子程序结构可以简化源程序书写、提高程序存储效率、减少出错率、增加程序的构可以简化源程序书写、提高程序存储效率、减少出错率、增加程序的易读性和可维护性,并且有利于子程序资源的组织和使用。设计子程序易读性和可维护性,并且有利于子程序资源的组织和使用。设计子程序时,除了必需要考虑程序调用、返回和完成特定功能的指令序列外,还时,除了必需要考虑程序调用、返回和完成特定功能的指令序列外,还必须注意解决子程序设计中具有共性的一些问题,即必须注意解决子程序设计中具有共性的一些问题,即: :现场保护、参数现场保护、参数传递、子程序的嵌套与递归调用、编写子程序说明文档等。传递、子程序的嵌套与递归调用、编写子程序说明文档等。 现场保护的目的是调用子程序之后,能够返回主程序继续执行。对现场保护的目的是调用子程序之后,能够返回主程序继续执行。对那些主程序和子程序中都会用到的一些寄存器要在子程序使用之前进行那些主程序和子程序中都会用到的一些寄存器要
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 消防自救知识培训会课件
- 论文课件模板复制
- 2025年液化天然气储运工安全生产模拟考试50题及答案
- 中国武侠电影研究知到智慧树答案
- 机房消防安全知识培训课件
- 2025年燃气从业人员考试题库及答案
- 消防知识技能培训心得课件
- 2025年二级建造师市政实务考试真题及答案解析【网友版】
- 城市体育公园活动组织与赛事策划方案
- 分布式光伏电站选址与资源评估方案
- 基层卫生岗位练兵和技能竞赛试题及答案(全科医疗组)
- 结直肠癌肝转移外科治疗策略2025
- 打造国际化教育环境-学校的外部合作关系构建
- JJG(京) 47-2013 出租汽车计价器(行车测距法)检定规程
- 5.3 一元一次方程的应用 七年级数学北师大版(2024)上册课时优化训练(含答案)
- 资产并购咨询合同模板
- 字画作品买卖合同模板
- 人教PEP版小学英语五年级下册复习教案(全册)
- NB-T 33025-2020 电动汽车快速更换电池箱通.用要求
- 【小升初】2024-2025学年四川省成都市下学期新七年级分班真题数学试题(含答案)
- 广东省深圳市2022-2023学年八年级下学期英语期末试卷(含答案)
评论
0/150
提交评论