汇编语言第6章子程序设计.ppt

上传人:tian****1990 文档编号:12721490 上传时间:2020-05-19 格式:PPT 页数:71 大小:333KB
返回 下载 相关 举报
汇编语言第6章子程序设计.ppt_第1页
第1页 / 共71页
汇编语言第6章子程序设计.ppt_第2页
第2页 / 共71页
汇编语言第6章子程序设计.ppt_第3页
第3页 / 共71页
点击查看更多>>
资源描述
6.1子程序的调用与返回指令,6.1.1子程序的调用指令CALL6.1.2返回指令RET,下一节,6.1.1子程序的调用指令CALL,指令格式:CALLOPD注:过程名或子程序名就是子程序入口处的符号地址。执行CALL指令时,首先要保留断点地址于堆栈中,然后程序转移到指定的子程序入口地址处去执行子程序。由于子程序与调用它的程序可能在同一个段中,也可以不在同一个段中,CALL指令在转移到子程序入口地址时有两种寻址方式:直接寻址方式和间接寻址方式或者称为直接调用和间接调用。前面提到,指令指针寄存器IP总是指向下一条将要执行的指令。在执行指令CALL时,堆栈中保存的就是原程序的断点地址(CALL指令后面1条指令的地址称为断点地址,也即返回地址)。,1.段内直接调用,在调用指令的目的操作数中直接给出过程名或子程序名。如CALLPROC1执行的操作:(SP)(SP)-2(SP)+1,(SP)(IP)(IP)(IP)+16位的位移量指令中的过程名或子程序名为NEAR属性,给出了转向地址(即子程序的入口地址,亦子程序的第一条指令的地址)。【例6.1】CALLDISPLAY1DISPLAY1PROCNEARRET,2.段内的间接调用,子程序的入口地址存放在一个16位通用寄存器或字存储单元中。在调用指令的目的操作数是除立即数寻址的某种寻址方式确定的有效地址EA。执行的操作是:(SP)(SP)-2(SP)+1,(SP)(IP)(IP)(EA)【例6.2】CALLBX;CALLWORDPTRBX,3.段间直接调用,调用指令的目的操作数中直接给出过程名或子程序名。如:CALLPROC2注:在不同的逻辑段中进行调用,直接调用的属性为FAR类型。执行的操作:(SP)(SP)-2(SP)+1,(SP)(CS)(IP)(EA)(SP)(SP)-2(SP)+1,(SP)(IP)(IP)偏移地址(CS)子程序的段基址【例6.3】CALLDISPLAY2DISPLAY2PROCFARRET,4.段内间接调用,子程序的入口地址存放在一个双字存储单元中,低地址的字单元存放入口地址的偏移量,高地址的字单元存放入口地址的段基址。执行的操作:(SP)(SP)-2(SP)+1,(SP)(CS)(IP)(EA)(SP)(SP)-2(SP)+1,(SP)(IP)(IP)(EA)(CS)(EA+2)【例6.4】CALLDWORDPTRBX,返回本章首,6.1.2返回指令RET,RET指令放在子程序的末尾,它使子程序的功能完成后返回到调用程序继续执行,而返回地址是调用指令时存入堆栈中的,回此RET指令的操作就是返回IP寄存器和CS寄存器的值。语句格式:RET执行段内RET指令时,从堆栈顶部弹出一个字(返回地址)送IP。执行段间RET指令时,从堆栈顶部弹出两个字(返回地址),分别送入IP和CS中。语句格式:RETn(n为偶数)指令中参数N应为偶数,如:2,4,6等。此指令先从堆顶弹出返回地址送IP或者IP和CS中,然后用参数N修改堆栈指针SP的值。SP=(SP)+N根据调用的不同,返回指令也分为:,1段内返回执行的操作:(IP)(SP)+1,(SP)(SP)(SP)+22段内带立即数返回RETN执行的操作:(IP)(SP)+1,(SP)(SP)(SP)+2(SP)(SP)+N,返回本章首,6.2子程序的设计方法,6.2.1子程序的定义6.2.2子程序的调用与返回6.2.3信息的保存与恢复,下一节,6.2.1子程序的定义,子程序的定义是由过程定义伪指令PROC和ENDP来完成的。其格式如下:过程名PROCNEAR/FAR过程名ENDP其中PROC表示过程定义开始,ENDP表示过程定义结束。过程名是过程入口地址的符号表示。一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性。当子程序和调用程序在同一个段时,子程序定义为NEAR属性;当子程序和调用程序不在同一个段时,子程序定义为FAR属性.,【例6.5】主程序和子程序在同一个代码段时的调用和定义CODESEGMENTMAINPROCFARCALLSUBPROG1RETMAINENDP;这一条指令也可以写在子程序结束之后SUBPROG1PROCNEARRETSUBPROG1ENDPCODEENDS,【例6.6】主程序和子程序不在同一个代码段时的调用和定义CODESEGMENTMAINPROCFARCALLSUBPROG1RETMAINENDPCODE1SEGMENTSUBPROG1PROCNEARRETSUBPROG1ENDPCODE1ENDS,返回本章首,6.2.2子程序的调用与返回,子程序的正确执行是由子程序的正确调用和正确返回保证的。汇编语言中子程序的调用指令CALL和返回指令RET来完成调用和返回功能。在前面学习CALL和RET指令时,在调用子程序时要把返回地址入堆栈,在返回时要把返回地址出栈,因此在子程序的设计中一定要特别注意堆栈的使用。,返回本章首,6.2.3信息的保存与恢复,由于主程序和子程序都具有相互独立的属性,而CPU中的寄存器是共用的,因此主程序和子程序在使用寄存器时有可能会发生冲突,也就是说主程序在调用子程序之前的某一个寄存器中的内容在从子程序返回后还要使用,而该寄存器在子程序中恰好被使用过,这样执行完子程序,相应的寄存器的内容就被改变,不是调用前主程序中该寄存器中原有的内容,从而当子程序执行完成后返回主程序执行时,主程序执行错误。为了避免类似这种错误,需要在进入子程序时,将子程序中涉及到主程序中的相应的寄存器内容进行保护,而在退出子程序之前恢复到原寄存器中,称这个为现场进行保护。,【例6.7】若子程序PROG中改变了寄存器AX,BX,CX,DX的值,则可采用如下方法保护和恢复现场。PROGPROCPUSHAXPUSHBXPUSHCX;保护现场PUSHDXPOPDXPOPCXPOPBX;恢复现场POPAXRET;返回断点处PROCENDP,返回本章首,6.3主程序与子程序参数传递方式,6.3.1寄存器法6.3.2用参数表传递参数6.3.3堆栈法,下一节,6.3主程序与子程序参数传递方式,调用程序在调用子程序时,经常需要向子程序传递一些参数,子程序运行结束后,有时候也需要向调用程序返回一些数据。这种在调用程序和子程序之间的信息的传递称为参数的传递(也中变量的传递)。汇编语言中,参数的传递方式有:,6.3.1寄存器法,此种方法,多用于参数较少的情况。其方法就是将要传递的参数放入指定的寄存器中,然后在子程序中再从指定的寄存器中将参数读出。【例6.8】从键盘输入一个十进制数,判断它的奇偶性,若为偶,在屏幕上显示”0”;若为奇,则显示”1”。程序中用寄存器BL进行参数的传递:,CODESEGMENTASSUMECS:CODESTART:MOVAH,01HINT21HCLCRCRAL,1JNCEVNMOVAL,31HMOVBL,ALCALLDISP,EVN:MOVAL,30HMOVBL,ALCALLDISPMOVAH,4CHINT21HDISPPROCNEARMOVAH,02HMOVDL,0AHINT21H,MOVDL,0DHINT21HMOVDL,BLINT21HRETDISPENDPCODEENDSENDSTART,返回本章首,6.3.2用参数表传递参数,这种参数传递方式通过定义一组连续的存储单元,即参数来进行参数的传递,将要传送的参数存放在参数表相应的存储单元内,然后把参数表的首地址通过BX寄存器传送到子程序中去。子程序通过访问参数表中相应的存储单元来获取所需的参数。,返回本章首页,【例6.9】,【例6.9】定义两个长度相同的数组A1、A2分别对两个数组求和、求差,并将结果保存数组A3、A4中。DATASEGMENTA1DB24,35,67,45,89,90,99LENEQU($-A1)A2DB22,30,45,34,12,2,6A3DBLENDUP(?)A4DBLENDUP(?)TABLEDW0,0,0,0,0DATAENDS,CODESEGMENTASSUEMCS:CODE,DS:DATMAINPROCFARPUSHDSMOVAX,0PUSHAXMOVAX,DATAMOVDS,AXMOVTABLE,OFFSETA1MOVTABLE+2,OFFSETA2MOVTABLE+4,LENMOVTABLE+6,A3MOVTABLE+8,A4,LEABX,TABLECALLADDA3CALLSUBA4RETMAINENDPADDA3PROCNEARPUSHAXPUSHCXPUSHSIPUSHDIMOVCX,BX+4,T1:MOVAL,BXADDAL,BX+2MOVBX+6,ALDECCXINCBXCMPCX,0JNZT1,POPDIPOPSIPOPCXPOPAXRETADDA3ENDPSUBA4PROCNEARPUSHAXPUSHCXPUSHSIPUSHDIMOVCX,BX+4,T1:MOVAL,BXSUBAL,BX+2MOVBX+8,ALDECCXINCBXCMPCX,0JNZT1POPDIPOPSIPOPCXPOPAXRETSUBA4ENDPCODEENDSENDMAIN,返回本章首,6.3.3堆栈法,此种方法适用于参数多、子程序嵌套调用和递归调用的情况。使用方法是调用程序在被调用子程序之前将参数压入堆栈,子程序从堆栈中取得参数。,【例6.10】,【例6.10】在数据段中存放着某班的三门课的成绩,求每门课的最高分,并分别存入到三个单无中。DATASEGMENTSCORE1DB91,62,63,84,76,76,78,55,64,64LEN1EQU$-SCORE1SCORE2DB66,64,64,65,45,62,77,89,99,69LEN2EQU$-SCORE2SCORE3DB77,88,92,63,21,64,83,88,81,53LEN3EQU$-SCORE3MAX1DB?MAX2DB?,MAX3DB?DATAENDSSTACKSEGMENTTABLEDW9DUP(?)TOPLABELWORDSTACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMAINPROCFARSTART:MOVAX,STACKMOVSS,AXPUSHSSMOVAX,DATAMOVDS,AXXORAX,AX,MOVSP,OFFSETTOPPUSHAXMOVBX,OFFSETSCORE1PUSHBXMOVBX,OFFSETMAX1PUSHBXMOVDX,LEN1PUSHDXMOVBX,OFFSETSCORE2PUSHBXMOVBX,OFFSETMAX2PUSHBXMOVDX,LEN2PUSHDXMOVBX,OFFSETSCORE3PUSHBXMOVBX,OFFSETMAX3,PUSHBXMOVDX,LEN3PUSHDXCALLPROCMAXCALLPROCMAXCALLPROCMAXPOPAXPOPDSPOPSSRETMAINENDPPROCMAXPROCNEARPOPCXPOPDIPOPBX,T1:CMPAL,BXJAET2XCHGAL,BXT2:INCBXLOOPT1MOVDI,ALRETPROCMAXENDPCODEENDSENDSTART,返回本章首,6.4子程序的嵌套与递归调用,6.4.1子程序的嵌套6.4.2子程序的递归调用,下一节,6.4.1子程序的嵌套,子程序不但可以被主程序调用,而且也可以被其他子程序调用。把一个子程序调用另一个子程序称为子程序的嵌套调用。子程序的嵌套调用示意图:,返回本章首,【例6.11】,【例6.11】要求从键盘接受本班同学的某科成绩,并按成绩排名输出学生学号,最多为50个人。程序的嵌套调用过程为:,图6.1,图6.1,图6.1,图6.1,图6.1,图6.1,图6.1,图6.1,图6.1,程序代码为:,DATASEGMENTGRADEDW50DUP(?)RANKDW50DUP(?)COUNTDW?MESS1DBGRADE?,$MESS2DB13,10,INPUTERROR!,13,10,$MESS3DBRANK:,$DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFAR,START:PUSHDSSUBAX,AXPUSHAXMOVAX,DATAMOVDS,AXCALLINPUTCALLRANKPCALLOUTPUTRETMAINENDPINPUTPROCNEARLEADX,MESS1MOVAH,09HINT21HMOVSI,0,MOVCOUNT,0ENTER:CALLDECIBININCCOUNTCMPDL,JESTORECMPDL,13JEEXIT2JNEERRORSTORE:MOVGRADESI,BXADDSI,2MOVDL,00HMOVAH,02HINT21HJMPENTER,ERROR:LEADX,MESS2MOVAH,09INT21HEXIT2:MOVGRADESI,BXCALLCRLFRETINPUTENDPRANKPPROCNEARMOVDI,COUNTMOVBX,0LOOP1:MOVAX,GRADEBXMOVWORDPTRRANKBX,0MOVCX,COUNTLEASI,GRADE,NEXT:CMPAX,SIJGNO_COUNTINCWORDPTRRANKBXNO_COUNT:ADDSI,2LOOPNEXTADDBX,2DECDIJNELOOP1RETRANKPENDPOUTPUTPROCNEAR,LEADX,MESS3MOVAH,09INT21HMOVSI,0MOVDI,COUNTNEXT1:MOVBX,RANKSICALLBINIDECMOVDL,MOVAH,02INT21HADDSI,2DECDIJNZNEXT1CALLCRLFRET,OUTPUTENDPDECIBINPROCNEARMOVBX,0NEWCHAR:MOVAH,1INT21HMOVDL,ALSUBAL,30HJLEXIT1CMPAL,9DJGEXIT1CBWXCHGAX,BXMOVCX,10DMULCXXCHGAX,BXADDBX,AXJMPNEWCHAR,XIT1:RETDECIBINENDPBINIDECPROCNEARPUSHBXPUSHCXPUSHSIPUSHDIMOVCX,100DCALLDEC_DIVMOVCX,10DCALLDEC_DIVMOVCX,1DCALLDEC_DIVPOPDIPOPSIPOPCXPOPBXRET,BINIDECENDPDEC_DIVPROCNEARMOVAX,BXMOVDX,0DIVCXMOVBX,DXMOVDL,ALADDDL,30HMOVAH,02HINT21HRETDEC_DIVENDPCRLFPROCNEAR,MOVDL,0AHMOVAH,02INT21HMOVDL,0DHMOVAH,02INT21HRETCRLFENDPCODEENDSENDSTART,返回本章首,6.4.2子程序的递归调用,子程序的递归调用是指一个子程序直接或间接地调用自己。递归子程序一般对应于数学上对函数的递归定义,它往往能设计出效率较高的程序,完成相当复杂的计算,因而是很有用的。,【例6.12】,【例6.12】试编制计算N!(N0)的程序。N!=N*(N-1)*(N-2)*1其递归定义如下:0!=1N!=N*(N-1)!(N1),【例4.16】,STACKSEGMENTSTACKDB200DUP(0)STACKENDSDATASEGMENTNDW5RESULTDW?DATAENDSCODESEGMENTASSUMECS:CODE,SS:STACK,DS:DATASTART:MOVAX,DATA,MOVDS,AXMOVAX,NCALLFACTMOVAX,RESULTMOVAH,4CHINT21HFACTPROCCMPAX,0JNEL1MOVRESULT,1JMPEXIT,L1:PUSHAXDECAXCALLFACTPOPAXMOVRESULTMOVRESNLT,AXEXIT:RETFACTENDPCODEENDSENDSTART,返回本章首,6.5子程序应用举例,【例6.13】将一个给定的二进制数按位转换成相应的ASCII码字符串,送到指定的存储单元并显示。如二进制数10010011转换成字符串为10010011。要求将转换过程写成子程序,且子程序应具有较好的通用性,而必须能实现对8倍和16倍二进制数的转换。入口参数:DX存放待转换的二进制数CX存放待转换数的位数(8位或16位)DI存放ASCII码首地址出口参数:转换后的字符串存放在以DI作指针的字节存贮区中程序如下:,DATASEGMENTNUM8DB93HNUM16DWABCDHASCBUFDB20DUP(0)DATAENDSCODESEGMENTASSUMEDS:DATA,CS:CODE,SS:STACKSTART:MOVAX,DATAMOVDS,AXMOVDX,0MOVDL,NUM8;转换二进制数送DXMOVCX,8;置位数8LEADI,ASCBUF;字符串首址DICALBTASC;调用子程序BTASC,MOVDI,BYTEPTR0DHMOVDI+1,BYTEPTR0AHMOVDI+2,BYTEPTR$LEADX,ASCBUFMOVAH,9INT21HMOVDX,NUM16MOVCX,16;置位数16LEADI,ASCBUFCALLBTASCMOVDL,BYTEPTR0DHMOVDL+1,BYTEPTR0AHMOVDL+2,BYTEPTR;显示转换后的字符串LEADX,ASCBUF,MOVAH,9INT21HBTASCPROCPUSHAX;保存AXMOVAL,0CMPCX,8;比较8位数JNEL1;直接转换16位数MOVDH,DL;8位数转换送DHL1:ROLDX,,1;DX最高位移入CFRCLAL,1;CF移入AL最低位ADDAL,30HMOVDI,AL,INCDILOOPL1POPAXRETBTASCENDPCODEENDSENDSTART,【例6.14】,【例6.14】从键盘接受一个十进制数,并以十六进制数形式在屏幕上显示。程序设计结构如下:,程序的代码为:CODESEGMENTASSUMECS:CODEMAINPROCFARCALLDECIBINCALLCRLFCALLBINIHEXCALLCRLFRETMAINENDPDECIBINPROCNEARMOVBX,0,NEWCHAR:MOVAH,01INT21HSUBAL,30HJLEXITCMPAL,9DJGEXITCBWXCHGAX,BXMOVCX,10DMULCXXCHGAX,BXADDBX,AXJMPNEWCHAREXITRET,DECIBINENDPBINIHEXPROCNEARMOVCH,4ROTATE:MOVCL,4ROLBX,CLMOVAL,BLANDAL,0FHADDAL,30HCMPAL,3AHJLPRINTITADDAL,7H,PRINTIT:MOVDL,ALMOVAH,2INT21HDECCHJNZROTATERETBINIHEXENDPCRLFPROCNEARMOVDL,0DHMOVAH,2INT21HMOVDL,0AH,MOVAH,2INT21HRETCRLFENDPCODEENDSENDMAIN,课后习题:,1、子程序是如何定义和调用的,请简要说明调用子程序和从子程序返回主程序的过程。2、用子程序实现,从键盘接受一个字符串,将大写字母转换为小写,将小写字母转换为大写,并显示原串和转换后的字符串。3、利用子程序,完成数组A1和A2的和与差,并将结果保存在A3和A4中。?4、编写一个子程序,完成N!。,Thankyouverymuch!,本章到此结束,谢谢您的光临!,返回本章首页,结束,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!