- 1、本文档共62页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
07-模块化程序设计方法
第7章 模块化程序设计方法 介绍: 子程序的定义与调用的基本方法 调用子程序时的参数传递方法 局部变量的概念及分配局部变量的一般方法 多模块程序的编译(汇编)连接方法 为编写大规模程序提供必要的基础 7.1 子程序的设计方法 功能和结构形式相同,只是某些参数的值不同,设计成子程序 设计子程序的同时就应当建立相应的说明文档,便于程序维护与使用 在规模稍大程序中,子程序往往放在一个单独的模块中,这便是程序设计的模块化 7.1.1 子程序定义、调用与返回 一般由伪指令PROC与ENDP来定义 过程名 PROC [NEAR/FAR] … ; 子程序代码 过程名 ENDP 过程名是标识符,表示过程的入口地址 是标号的一种形式,也是一个符号地址 用CALL指令来调用子程序,在子程序中用RET指令返回到调用程序 若子程序定义成Near属性,汇编程序将RET翻译成近返回 (RETN),将CALL翻译成直接近调用指令 若子程序定义成Far属性,编程序将RET翻译成远返回(RETF),将CALL翻译成直接远调用指令 例7.1 在下面程序中定义了两个子程序:DisplayString和CRLF,分别是显示字符串和回车换行,并调用它们 子程序属性的确定原则很简单,即: ① 如调用程序和子程序在同一个代码段中,则使用Near属性。 ② 如调用程序和子程序不在同一个代码段中,则使用Far属性 直接调用的CALL指令后也可以是标号 7.1.2 寄存器的保护与恢复 主程序和子程序通常是分别编制的,所以它们所使用的寄存器往往会发生冲突 进入子程序后,把子程序所需要使用的寄存器内容保存在堆栈中,此过程称作寄存器保护 在退出子程序前把寄存器内容恢复原状,此过程称作寄存器恢复 寄存器保护与现场恢复分别使用压栈和出栈指令实现 使用堆栈来实现寄存器的保护与恢复这项功能时,应注意: 对寄存器内容保护和恢复所进行进栈和出栈的操作次序刚好相反; 通常不保护入口参数寄存器的内容,当然也可根据事先的约定而对它们加以保护; 如果用寄存器传递子程序的处理结果,那么这些寄存器就一定不能加以保护; 根据需要,可用PUSHF和POPF来保护和恢复标志位。 7.1.3 子程序的参数传递 主程序在调用子程序时,经常要向子程序传递一些参数或控制信息,子程序执行后,也常需要把运行的结果返回调用程序。这种信息传递称为参数传递 常用的方法有: 约定寄存器传递参数 约定内存单元传递参数 堆栈传递参数 经常同时使用 1. 约定寄存器传递参数 调用程序将要传递的参数预先放入事先约定的寄存器中,转入子程序后再取出进行处理; 子程序也可将处理结果放入事先约定的寄存器中,传递给调用程序 例7.2 编写程序,输入一个16位无符号数,再以十六进制形式显示出来 例7.3 编写程序,求n个16位补码数的累加和,并以十进制形式显示出来 三个子程序: TotalByReg,计算数组的累加和,约定数组首地址存放在SI,长度存放在CX中,计算结果通过AX返回给调用程序; Dispsi16ByDX,以十进制形式输出16位补码数,约定调用程序用DX向子程序传递补码数; CRLF,执行回车换行 2. 约定内存单元传递参数 调用程序和子程序都按事先的约定,在指定的内存单元中进行数据交换 调用程序在调用子程序前,把要传送给子程序的参数都存放在约定的内存区中,再调用子程序, 子程序从约定的单元中取出所需参数; 例7.4 使用约定内存单元传递参数,重新编写例7.3的程序。 对于求累加和的子程序,改为用约定内存单元传递参数,并命名为TotalByMem,约定数组首地址存放在PA,长度存放在Count中,计算结果存入Result。 3. 通过堆栈传递参数 调用程序按事先约定的次序,把要传递的参数压入堆栈,然后调用子程序;子程序按相同的次序,从堆栈中取出相应的参数来使用 通常情况下,约定用堆栈传递入口参数,用寄存器传递返回结果。 使用堆栈传递参数时,当子程序执行结束返回后,先前压入堆栈的参数不再有用,应当丢弃,必须把堆栈指针调整到调用前的状态。 如果是调用程序来调整,则在CALL指令后,加上一条形如“ADD SP, n”(16位地址模式)或“ADD ESP, n”(32位地址模式)的指令; 如果是子程序来调整,那么须在RET指令后带有一个立即数,即执行形如“RET n”的指令返回到调用程序 例7.5 用堆栈传递参数,重新编写例7.3的程序。 三个子程序: Total,求数组的累加和,用堆栈来传递参数,进栈次序约定为:先压入数组首地址,再压入数组长度,计算结果约定存入AX中; Dispsi16,以十进制形式显示一个16位补码数,也是用堆栈传递一个补码数; CRLF执行回车换行 用堆栈传递参数的一般形式 子程序调
文档评论(0)