IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计

上传人:E**** 文档编号:89191608 上传时间:2019-05-21 格式:PPT 页数:53 大小:318.50KB
返回 下载 相关 举报
IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计_第1页
第1页 / 共53页
IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计_第2页
第2页 / 共53页
IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计_第3页
第3页 / 共53页
IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计_第4页
第4页 / 共53页
IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计_第5页
第5页 / 共53页
点击查看更多>>
资源描述

《IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计》由会员分享,可在线阅读,更多相关《IBM-PC汇编语言程序设计 教学课件 ppt 作者 余朝琨 第11章 子程序结构程序设计(53页珍藏版)》请在金锄头文库上搜索。

1、第11章子程序结构程序设计 11.1 概述 11.2 子程序的结构形式 11.3 子程序设计方法 11.4 子程序设计举例 11.5 DOS系统功能调用,返回主目录,调用子程序使用CALL指令。根据CALL指令功能,它首先要将其下一条指令地址(返回地址或称为断点地址)自动保存到堆栈中,然后将转移到子程序的入口开始执行子程序,当子程序执行完后,通过RET指令返回。根据RET指令功能,它将从堆栈中弹出原先保存的返回地址,实现子程序返回到断点处继续执行主程序。返回点地址的入栈和出栈操作都是通过CALL和RET指令自动实现的,不需要用户介入这一操作。编程者只要在适当的位置正确地使用这两条指令就可以了。

2、 由于使用子程序设计,要增加返回点地址的入、出栈操作,有时还需要对有关的寄存器内容进行现场保护和现场恢复的操作,这就使程序执行中额外地耗费了计算机的时间。但子程序的使用,可以简化程序、方便程序的调试、减少占用内存单元、可以共享某些子程序等,这都是使用主程序的优点。所以子程序设计还是无一例外地被广泛用在程序设计中。 综上所述,采用子程序结构,可归纳出几个方面的优点: (1) 简化了程序设计过程,使程序设计时间大量节省; (2) 缩短了程序的长度,节省了程序的存储空间; (3) 增加了程序的可读性,使程序更加清晰,便于对程序的修改与调试; (4) 方便了程序的模块化、结构化和自顶向下的程序设计过程

3、。,11.2 子程序的结构形式 一个完整的子程序结构形式,主要包括以下几个方面的内容。 11.2.1 子程序说明文件 一般子程序是以子程序文件的形式存在,子程序文件又由文字说明和子程序本身两部分构成。子程序文字说明为子程序的使用者提供足够的信息,使程序员不需查看子程序的内部结构或者程序本身,就可以决定是否选用它。子程序说明文件一般应包含以下几项的内容: 子程序名:一般取具有顾名思义的标识符; 子程序的功能:说明子程序要完成的具体任务; 子程序所选用寄存器名,存储单元的分配情况; 子程序的入口参数:说明子程序运行中所需要的参数及存放位置; 子程序的出口参数:说明子程序运行结束后的结果参数及存放位

4、置; 子程序示例:通过所举示范性的例子,把具体的参数值代入,使之更具体了解子程序的功能,并且还能起到验证的作用。,例如,有一个子程序说明文件为: ;子程序名:DCB ;功能:完成将一字节的压缩BCD码转换成二进制数。 ;输入参数:AL寄存器中存放要转换的压缩BCD码。 ;输出参数:CL寄存器中存放转换后的二进制数。 ;要使用的寄存器:AX,BX,CX ;示例:输入AL=01101001B (69H代表十进制数69编码) 输出CL=01000101B (十进制数69的二进制编码) 11.2.2 子程序的现场保护和现场恢复 在编写子程序时,要选用各种寄存器。有些寄存器在调用子程序前,可能已被使用过

5、,并且在执行完子程序返回后,仍然要用到这些寄存器的内容,这样主程序与子程序在寄存器的使用上就有可能发生冲突。因此,就出现了如何保护寄存器的问题,也就是现场保护和现场恢复的问题必须妥善解决。,如果调用程序(主程序)在调用子程序之前,所有寄存器都属于空闲待用状态,在这种情况下,就没有必要考虑寄存器的保护问题。只要正确安排哪些寄存器作为入口参数或出口参数即可;如果寄存器不空闲(后续指令还使用这些寄存器中的内容),则就要考虑对其施加保护。需要保护的寄存器,它将在子程序中被使用,而返回到调用程序后仍然需要使用其原有内容的那些寄存器。即保护调用程序和子程序两者在使用上发生冲突的那些寄存器。但在编程时,一时

6、很难弄清哪些是有冲突的寄存器,一种较为简单的方法是把所有的寄存器加以保护。 在什么地方保护,是在主程序中保护,还是在子程序中保护?是编写带有子程序的程序时应该认真考虑的一个问题。 通常情况下在子程序中进行寄存器保护较好。特别是作为一个通用子程序,使用者并不一定了解子程序中将使用了哪些寄存器,若由主程序来保护,在未对子程序做深入了解时,难免带有盲目性,因此在这种情况下寄存器的保护工作应由子程序来承担。即在子程序的开始部分,先进行相关寄存器,主要是在子程序中使用的各寄存器的保护。然后再进行子程序的处理操作。在执行完子程序后,返回前,先恢复各相关寄存器内容后,再执行返回指令,返回到断点处继续执行被打

7、断的程序。,如果在主程序中进行保护,应对在主程序中使用过,在调用主程序返回后仍然要使用原有信息的那些寄存器进行保护,然后再调用子程序。在从子程序返回后,再恢复各寄存器内容,从而不会破坏原来程序对寄存器的使用要求。 从以上分析可知,保护现场和恢复现场的工作既可在主程序中完成,也可在子程序中完成。这可根据用户在程序设计时自行安排。如果子程序设计时,未考虑保护主程序的现场,则可在主程序调用子程序前进行保护现场,从子程序返回后恢复现场。通常在主程序中保护现场,就一定在主程序中恢复;在子程序中保护现场则一定要在子程序中恢复。这样安排,程序结构清楚,使用方便,不易出错。 现场保护和现场恢复常采用的方法:

8、1利用堆栈保护现场与恢复现场 利用进栈指令PUSH,将寄存器的内容保存在堆栈中,恢复时再用出栈指令POP从堆栈中弹出。这种方法较为方便,尤其在设计嵌套子程序和递归子程序时,由于进栈和出栈指令会自动修改堆栈指针,保护和恢复现场层次清晰,只要注意堆栈操作的先进后出的特点,只要正确使用进出栈指令,就不会引起出错,这是一种常用方法。,【例111】 SUB1 PROC NEAR PUSH AX ; PUSH BX ; 保护现场 PUSH CX ; PUSH DX ; ; 子程序处理 POP DX ; POP CX ; 恢复现场 POP BX ; POP AX ; RET SUB1 ENDP 2利用内存单

9、元保护现场与恢复现场 利用数据传送指令将主程序所占用的寄存器内容保存到指定的内存单元中,恢复现场时再用数据传送指令(读操作),从指定的内存单元中取回到对应的寄存器中。这方法使用时不太方便,故较少使用。,【例112】 BUF DW 10H DUP(?) SUB1 PROC NEAR MOV DI,OFFSET BUF MOV DI,AX ;保护现场 MOV DI+2,BX MOV DI+4,CX MOV DI+6,DX LEA SI,BUF ;恢复现场 MOV AX,SI MOV BX,SI+2 MOV CX,SI+4 MOV DX,SI+6 RET SUB1 ENDP 3利用寄存器保护现场与恢

10、复现场 在主程序与子程序中,能够发生冲突的寄存器较少,且有富余待选用的寄存器时,可利用这些待用寄存器保护现场与恢复现场。如BP寄存器为待用,主、子程序中发生冲突寄存器仅为AX,就可利用BP来保护与恢复。,【例113】 SUB1 PROC NEAR MOV BP,AX ;保护AX的内容 MOV AX,BP ;恢复AX的内容 RET SUB1 ENDP 11.2.3 子程序的调用和返回 在程序设计时,为了使程序的结构清晰,增加可读性,一般都用过程(子程序)定义语句:PROCENDP,将子程序定义为独立的程序段,并说明是NEAR类型还是FAR类型。具有NEAR类型的子程序中的RET指令,汇编成段内(

11、近)返回指令,它不能被其它代码段的程序调用。要使子程序既可以被本代码段的程序调用,又可被其它代码段的程序调用,该子程序必须在过程定义语句中被说明为FAR类型属性,其返回指令RET将被汇编成段间(远程)返回指令。段内与段间返回指令RET的机器代码不同。 1子程序段内调用和返回 一个段内调用的子程序,可直接定义在代码段中,如果有多个子程序,都是段内调用,可以在代码段中任意位置定义它们,可置于主程序前面或放在主程序后面都是允许的,但是将它们放在主程序中间,就必须注意主程序指令之间的连接关系,否则就很容易出错。,【例114】子程序及其调用之例。 要求:在A、B字节单元中各存有一个无符号数,完成二个无符

12、号数的加法及减法运算,并将其结果在屏幕上以十进制数形式显示。要求用子程序编写加、减运算以及二进制到十进制数转换的程序。 注:本例要求实现的加、减运算及二进制数转换成十进制数显示的程序段,都是很容易编写的,其目的就在于利用很简单的例子来了解主程序对子程序的调用关系。为方便起见,假定两数相加或相减,其结果都为二位正的十进制数。 DATA SEGMENT A DB 66 B DB 28 C DB ? ;存加数的和 D DB ? ;存差 DATA ENDS STAK SEGMENT STACK DW 50 DUP(?) STAK ENDS CODE SEGMENT ASSUME CS:CODE,DS:

13、DATA,START: MOV AX,DATA MOV DS,AX LEA SI,A LEA DI,B CALL SADD ;调用加法子程序 CALL OUTD ;调用显示子程序 CALL SSUB ;调用减法子程序 CALL OUTD MOV AH,4CH INT 21H ;主程序返回DOS SADD PROC NEAR ;加法子程序(过程) MOV AL,SI ADD AL,DI MOV C,AL ;存和数 RET SADD ENDP SSUB PROC NEAR ;减法子程序(过程) MOV AL,SI SUB AL,DI MOV D,AL ;存差 RET SSUB ENDP,DISP

14、PROC NEAR ;显示单字符子程序 OR DL,30H MOV AH,2 INT 21H RET DISP ENDP OUTD PROC MOV AH,0 MOV BL,10 DIV BL MOV DL,AL ;显示十位数 MOV DH,AH ;暂存个位数 CALL DISP MOV DL,DH CALL DISP MOV AH,2 MOV DL,0DH ;回车 INT 21H MOV DL,0AH ;换行 INT 21H RET OUTD ENDP CODE ENDS END START,2子程序段间调用和返回 子程序段间调用和段间转移有些相似,它们都是在不同段之间进行程序转移。它们不象

15、段内调用或转移那样简单。 段间调用有些特殊考虑与处理。 段间调用的子程序(过程)必须定义成FAR类型。调用FAR类型子程序的CALL指令,在保存断点(返回地址)时不仅要保存断点的偏移地址IP,而且代码段的段基值CS也要保存。当执行指令RET返回时,要将断点的偏移地址与段基值分别送入IP与CS。 段间调用和返回所使用的CALL和RET指令能够自动实现上述操作,用户不必为此操心。 子程序的段间调用,多用于不同模块之间的调用。而在同一模块中,通常只设一个代码段,只要用段内调用就可以了。但若同一模块被设计成多个代码段,则过程名仍须定义为FAR类型。 编制不同模块的段间调用,需要解决的问题是:调用过程的程序段和定义过程的程序段(即子程序),通常它们分别处在不同的代码段中。所以不同的模块应该单独汇编,再经连接程序连接,才能将它们组合在一起。,调用程序段所调用的外部过程名必须用EXTRN伪指令在代码段内进行说明,并指明它们的类型属性。而过程所在的程序段中,必须用PUBLIC伪指令对提供给其它段调用的过程名进行公用说明。这两个伪指令所说明的过程名、标号名及变量名,在汇编时,汇编程序将根据这些说明才能进行有效的连接,并产生段间调用的CALL和RET指令代码。由连接程序(LINK)连接后,就最终将它们之间的关系正式连接在一起了。这样才可以实现子程序的段间调用。 以下例子仅供读者了解与体

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号