第5章子程序107

上传人:无*** 文档编号:247323351 上传时间:2024-10-17 格式:PPT 页数:156 大小:651KB
返回 下载 相关 举报
第5章子程序107_第1页
第1页 / 共156页
第5章子程序107_第2页
第2页 / 共156页
第5章子程序107_第3页
第3页 / 共156页
点击查看更多>>
资源描述
*,新 编,汇编语言程序设计,1,第五章子程序,5.1,子程序,5.2,参数的传递,5.3,嵌套和递归子程序,5.4,多模块程序设计,5.5,汇编语言与,C,语言混合编程,5.6,DOS,和,BIOS,调用,习题五,2,子程序(,Subroutine,),:,把程序需要完成的任务分解为若干个“子任务”,每个“子任务”由一段相对独立的程序完成,称为“子程序”。,调用子程序的程序称为“主程序”或者“主调程序”。,子程序也称为“过程”(,Procedure),,在高级语言里还称作“函数”(,Function)。,3,子程序结构程序的优点,:,1.,程序结构清晰,提高了程序的可阅读性和可维护性。,2.,每个子程序可以独立地进行调试,由于程序规模较小,降低了调试难度。,3.,每个子程序就是一个具有特定功能的独立的程序,提高程序的“可重用性”,提高了软件开发效率。,4,图,5-1,子程序的调用和返回,5,近程子程序,:,只能被同一个代码段里的程序调用的子程序。,由于主程序和子程序处于同一个代码段,调用和返回时只需要改变,IP,寄存器的值,,CS,寄存器的值保持不变。,近程子程序的入口地址用,16,位段内偏移地址表示。,6,远程子程序,:,能够被不同代码段的程序调用,也能被同一代码段的程序调用的子程序。,调用这样的子程序时,需要同时改变,CS,和,IP,寄存器的值,返回时,需要从堆栈里弹出,32,位的返回地址送入,IP,CS,寄存器。,远程子程序的入口地址用,16,位段基址和,16,位段内偏移地址表示。,子程序的类型在定义时说明,7,5.1,子程序,5.1.1,CALL,和,RET,指令,5.1.2,子程序的定义,5.1.3,子程序文件,5.1.4,子程序应用,8,CALL(Call,,调用)指令,段内直接调用,格式:,CALL,子程序名,操作:,SP SP-2,SS:SP IP(,保存,16,位返回地址),IP,子程序入口的偏移地址,例如:,CALLPROC1,段内间接调用,格式:,CALLREG16/MEM16,操作:,SP SP-2,SS:SP IP(,保护,16,位返回地址),IP REG16/MEM16,5.1.1,CALL,和,RET,指令,9,例如:调用名为“,PROC1”,的近程子程序。,(1,),CALLPROC1,(2)LEA CX,PROC1,CALL CX,(3)ADDR_PROC1 DW PROC1,;,子程序偏移地址放入存储器字变量,CALLADDR_PROC1;,调用近程子程序,PROC1,(4),LEABX,ADDR_PROC1,CALLWORD PTR BX;,调用近程子程序,PROC1,10,段间直接调用,格式:,CALL FAR PTR,子程序名,操作:,SP SP-2,SS:SP CS,SP SP-2,SS:SP IP,(,保存,32,位返回地址,偏移地址保存在较小地址处),IP,子程序入口的偏移地址,,CS,子程序入口的段基址,CALL FAR PTR PROC2,例如:,11,段间间接调用,格式:,CALL MEM32,操作:,SP SP-2,SS:SP CS,SP SP-2,SS:SP IP,IP MEM32,CSMEM32+2,例如:,ADD_PROC2 DD PROC2,;,子程序入口地址放入存储器双字变量,CALLADD_PROC2 ;,调用远程子程序,PROC2,12,无参数段内返回,格式:,RET,操作:,IP SS:SP,SP SP+2,有参数段内返回,格式:,RET D16,操作:,IP SS:SP,SP SP+2,SP SP+D16,RET(Return,,返回)指令,13,无参数段间返回,格式:,RET,操作:,IP SS:SP,SP SP+2,CS SS:SP,SP SP+2,有参数段间返回,格式:,RET D16,操作:,IP SS:SP,SP SP+2,CS SS:SP,SP SP+2,SP SP+D16,14,5.1.2,子程序的定义,子程序名,PROC NEAR/FAR,子程序体,子程序名,ENDP,15,说明,:,子程序名应为合法的标识符,子程序名不能与同一个源程序中的标号、变量名、其它子程序名相同。,方括号中的内容是子程序的远近属性选项,二者可选其一,如果缺省,默认为,NEAR。,用,NEAR,说明的子程序是“近程子程序”,它只能被与它同一代码段的程序调用。,用,FAR,说明的子程序是“远程子程序”,它不仅能被与它同一代码段的程序调用,也能被其它代码段的程序调用。,子程序的定义要写在代码段内,16,ZEROBYTESPROC;,定义一个子程序,XORAX,AX;AX,清零,MOVCX,128;,循环次数送,CX,ZEROLOOP:MOVBX,AX;,将一个字存储单元清零,ADDBX,2;,修改地址,LOOP ZEROLOOP;,循环控制,RET;,返回主程序,ZEROBYTESENDP;,子程序结束,思考题,:该子程序完成了什么功能?调用该子程序时,应该先做什么准备工作?,17,ZEROBYTES:XOR AX,AX;AX,寄存器清零,MOVCX,128;,计数器,CX,置初值,ZEROLOOP:MOVBX,AX;,一个字单元清零,ADDBX,2 ;,修改地址指针,指向下一个字,LOOPZEROLOOP;,循环控制,RET ;,结束程序运行,返回主程序,子程序也可以简单地写成下面的形式:,缺点:边界不容易清晰地区分;只能定义“近程子程序”;只能被同一代码段内的程序调用,。,18,CODESEGMENT;,代码段开始,MAINPROC FAR;,主程序开始,;,主程序的指令序列,MOVAX,4C00H,INT21H;,返回,DOS,MAINENDP;,主程序结束,;,其它程序,CODEENDS;,代码段结束,ENDMAIN;,源程序结束,用户编写的“主程序”也可以看作是由操作系统调用的一个子程序:,19,CODESEGMENT;,代码段开始,MAINPROC FAR;,主程序开始,PUSHDS ;,操作系统的返回点在,DS:0,XORAX,AX,PUSHAX ;,把32,位返回点地址压入堆栈,;,主程序的指令序列,RET;,返回,DOS,MAINENDP;,主程序结束,;,其它程序,CODEENDS;,代码段结束,ENDMAIN;,源程序结束,还可以这样写:,20,例,5.1,子程序,FRACTOR,用来计算一个数的阶乘。主程序利用它计算,15,的阶乘,存入,FRA,数组。,.386,DATASEGMENTUSE16,FRADW5 DUP(?),DATAENDS,21,CODESEGMENTUSE16,ASSUME CS:CODE,DS:DATA,START:MOV AX,DATA,MOVDS,AX,MOVEBX,1;BX,中存放待求阶乘的数,MOVCX,5;,求阶乘次数(循环次数),LOOP0:CALL FRACTOR;,调用,FRACTOR,求阶乘,MOVFRA2*EBX-2,AX;,保存结果(阶乘),INCBX;,产生下一个待求阶乘的数,LOOPLOOP0;,循环控制,MOV AX,4C00H,INT21H,22,FRACTOR PROC NEAR,MOV CX,BX;,待求阶乘的数转入,;,CX,寄存器,MOVAX,1;“,累乘器”置初值,1,FRALOOP:MULCX;,累乘,LOOPFRALOOP;,循环控制,RET,FRACTORENDP,CODEENDS,ENDSTART,思考题:这个程序有问题,是什么问题?如何解决?,23,FRACTOR PROC NEAR,PUSHCX,;CX,压入堆栈保护,MOV CX,BX,;,待求阶乘的数转入,CX,寄存器,MOVAX,1;“,累乘器”置初值,1,FRALOOP:MULCX;,累乘,LOOPFRALOOP;,循环控制,POPCX ;,从堆栈里弹出,CX,的原值,RET,FRACTORENDP,CODEENDS,ENDSTART,在子程序入口处把相关寄存器的值入栈保护,程序返回前再恢复它们的值,这个操作称为“保护现场”和“恢复现场”。,24,注意:,上面的程序使用了,32,位寻址方式,连接时在,TLINK,命令中要增加“,/3”,选择项:,TLINK /3 XXXXXX,(XXXXXX,为汇编得到的目标文件名),25,子程序的基本格式:,子程序名,PROCNEAR/FAR,PUSH;,保护现场(寄存器,/,存储器),PUSH;,个数根据具体情况决定,;,子程序主体,POP ;,恢复现场,注意出栈次序,POP ;,先进栈的寄存器后出栈,RET;,返回,子程序名,ENDP,26,5.1.3,子程序文件,设计一个子程序之前,首先应该明确:,子程序的名字,;,子程序的功能,;,入口参数,:,为了运行这个子程序,主程序为它准备了哪几个,“,已知条件,”,?这些参数存放在什么地方?,出口参数,:,这个子程序的运行结果有哪些?存放在什么地方?,影响寄存器,:,执行这个子程序会改变哪几个寄存器的值?,其它需要说明的事项,。,上述内容连同子程序源代码等合称为“,子程序文件,”。,常常把上述内容以“程序注释”的方式书写在一个子程序的首部。,27,;,名称:,Square,;,功能:求,16,Bit,无符号数的平方根,;,入口参数:,16,Bit,无符号数在,AX,中,;,出口参数:,8,Bit,平方根数在,AL,中,;,影响寄存器:,AX(AL),例如,一个名为“,SQUARE”,的子程序,用来求一个数的平方根,源程序如下:,28,SQUAREPROC NEAR,PUSHCX;,保护现场,PUSHBX,MOVBX,AX;,要求平方根的数送,BX,MOVAL,0;AL,中存放平方根,初值,0,MOVCX,1;CX,置入第一个奇数,1,;,利用公式:,N2=1+3+(2N-1),求平方根,29,NEXT:SUBBX,CX,JBDONE,ADDCX,2;,形成下一个奇数,INCAL;AL,存放已减去奇数的个数,JMPNEXT,DONE:POPBX;,恢复现场,POPCX,RET;,返回,SQUAREENDP,课内练习:编写主程序,利用,SQUARE,子程序,求数,26,的平方根,存放在变量,ROOT,中。,30,5.1.4,子程序应用,每调用一次子程序,主程序需要做三件事:,(1,)为子程序准备入口参数,(,2,)调用子程序,(,3,)处理子程序的返回参数,31,DATA SEGMENT,X DW 59,3500,139,199,77 ;,欲求平方根的数组,ROOT DB5 DUP(?);,存放平方根内存区,DATA ENDS,CODESEGMENT,ASSUMECS:CODE,DS:DATA,START:MOVAX,DATA,MOVDS,AX,例,,为了求,5,个无符号数的平方根,编制主程序如下:,32,LEABX,X;,初始化指针,LEASI,ROOT,MOVCX,5;,设置计数器初值,ONE:MOVAX,BX;,设置入口参数,CALLSQUARE;,调用子程序,MOVSI,AL,;,保存返回参数(平方根),ADDBX,2,;,修改指针,INCSI;,修改指针,LOOPONE;,循环控制,MOVAX,4C00H;,返回,DOS,INT21H,33,例5.2,从键盘上输入,10,个十进制数,从中找出最大的数,在屏幕上显示出来。,INCLUDEYLIB.H;,声明外部函数,.,DATA,NUMDW10DUP(?),PROMPT1DB0AH,0DH,“Input a Number:$”,PROMPT2DB0AH,0DH,“The Maximum Number is:$”,34,.,CODE,START:MOV AX,DATA,MOVDS,AX,MOVCX,10,LEABX,NUM,NEXT:LEADX,PROMPT1,;,设置,READINT,子程序的入口参数,CALL READINT,MOV BX,AX;,保存读入的
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


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

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


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