黄老师 发表于 2013-8-18 08:25:14

大工13春《汇编语言程序设计》辅导资料十一

大工13春《汇编语言程序设计》辅导资料十一
主    题:第六章子程序结构(第1-2节)
学习时间:2013年6月10日-6月16日
内    容:
第六章第1-2节概述
这周我们学习第六章中的前两节,学习子程序的结构特点和作用,并通过几个程序例子具体讲解子程序的设计方法。子程序相当于其他高级语言中的函数或者过程,也是汇编语言四种基本程序结构之一,因此掌握好子程序的设计显得很重要。
第1节子程序结构及设计方法
1)子程序概念:子程序又称为过程,它相当于其他高级语言中的过程和函数,是一个可以重复调用的功能模块。
2)过程定义伪操作:子程序定义也需要标准的定义格式:
PROCEDURE NAME      PROC       ATRRIBUTE
                        …
PROCEDURE NAME      ENDP
说明:过程名即子程序名就是子程序的入口符号地址,属性可以使NEAR和FAR。子程序调用指令CALL和返回指令RET也有NEAR和FAR属性,调用返回指令属性与子程序属性相对应,但是调用和返回属性须依照子程序属性。NEAR和FAR判断标准如下:
    调用程序与过程在同一代码段中,则用NEAR属性;
    调用程序与过程不在同一个代码段中,则用FAR属性
    另外,过程定义格式中可以嵌套其他的过程定义,即过程定义可以嵌套。
3)子程序的调用与返回:进入子程序和退出子程序需要做的准备工作,把调用程序与子程序公用的寄存器保存入栈,并且返回子程序时先将这些寄存器出栈,这样在返回调用程序时就不会影响到其所用各寄存器的内容。这项操作常见的方法是连续的一串PUSH入栈指令及POP出栈指令。从80386开始,这些压栈指令就可以用PUSHAD/POPAD指令取代,为子程序中保存和恢复寄存器提供了方便。
   子程序设计时就应该仔细考虑好哪些寄存器是需要保存的,哪些是不需要保存的。一般子程序用到的寄存器是应该保存的,但是如果是用来传送参数的话就不应该保存,否则就会造成调用函数无法正确获取回送参数(后面回讲到)的问题
4)子程序的参数传送:子程序被调用时,常需要回送一些参数给调用程序,这种调用程序与子程序间的信息传送称为参数传送
5)参数传递的几种方式:
 通过寄存器传送参数:这是最常见到的方式,后续的几种方法也是基于寄存器传送方式传送参数的,举例如下
十进制数到十六进制数的转换程:从键盘取得一个十进制数转换成十六进制数并显示出来。程序结构图如下,具体程序可以参考课件及参考书:
                  
JI
说明:DECIBIN和BINIHEX是两个子程序,其作用十进制转换二进制和二进制转换十六进制,屏幕显示问题由DOS调用实现。第三个CRCL子程序的作用就是为了避免屏幕的重叠。三个子程序间参数的传递用BX寄存器来实现。这也是最基本的参数传递方式。
 直接访问同模块中变量:这需要调用程序与子程序在同一源文件中(同一程序模块中),举例如下:
MAIN主调程序和PROADD子程序在同一源文件内,PROADD的功能是把数组中所有元素累加并把和送到指定的寄存器中。本程序的实现就可以在PROADD中直接访问源文件(模块)的数据区。
         
 (3)地址表传送参数地址:这种参数传递方法需要先创建地址表,然后在子程序中可以直接访问这个地址表,从而取得操作数,数据处理后再将结果存入指定的地址表单元中供主调程序使用。
      这种方式本质上还是寄存器传送参数,因为在传送地址表表头地址的偏移地址时还需要寄存器的参与。参考书中有具体程序实例,大家可以去研究一下。      
 (4)堆栈传送参数或参数地址:这种方式是在主程序中把参数地址保存到堆栈中,在子程序里从堆栈中取出参数以达到传送参数的目的。这种参数传送过程可以概括如下:
       ⅰ 堆栈段内建立地址表
       ⅱ SP置栈顶
       ⅲ 变量地址入栈,SP入栈
       ⅳ SP值保存到BP中
       ⅴ通过BP间接寻址将数据段内数据传入子程序
堆栈段栈满状态示意图如下:
      
    SP(新)→
         


         (BP)→
    (原(SP)→)
返回地址



说明:SUM,COUNT ARY地址是参考书中子程序返回参数的地址,具体代表累加和计数器和数组的符号地址。
 (5)多模块间的参数传送问题:这里介绍下两个外部符号相关的伪操作,这已经可以解决不同模块中主调程序和子程序间参数传送问题
            局部符号和外部符号:源程序中用户定义的符号可以分为局部符号和外部符号,在本模块中定义又在本模块中引用的符号称为局部符号;在一个模块中定义而在另一模块中引用的符号称为外部符号,下面介绍两个与外部符号相关的伪操作:PUBLIC伪操作和EXTRN伪操作
          PUBLIC伪操作:其作用是在一个模块中定义的符号供其他模块调用时需要使用PUBLIC伪操作,这样其他模块才可以调用本模块相应的符号
          EXTRN伪操作:其作用是在另一模块中定义而在本模块中需要引用其符号时必须使用EXTRN伪操作,这样才可以调用其他模块中相应的符号
       注意:外部符号和内部符号,全局变量和局部变量的区别。
   6)子程序的嵌套:一个子程序可以作为调用程序去调用另一个子程序,这种情况就称为子程序的嵌套,当调用的子程序是其自身时就形成了递归调用,递归调用在数学上也是一种和有用的方法,类似于枚举归纳法,有一类问题必须使用递归调用才能实现。
第2节 子程序举例
1)地址表传送参数法的程序段如下,其程序功能在上述参数传递中已经涉及,完整程序可以参考老师课件和参考书:
   Mov table,offset ary            
   Mov table+2,offset count
   Mov table+4,offset sum 创建地址表并调用PROADD过程
   Mov bx,offset table
   Call proadd BX寄存器内容是地址表首地址
      
      PROADD   PROC    NEAR
               PUSH AX
                PUSH CX
                PUSH SI
                PUSH DI
                MOV SI,            ;SI获取数组首地址
                MOV DI,            ;DI获取COUNT首地址
                MOV CX,            ;CX获取数组首元素值,也即数组元素数量
                ……..
本周要求掌握的内容如下:
基本概念:子程序概念和作用、子程序调用和返回过程、子程序和调用程序的属性匹配、NEAR属性与FAR属性的判断、参数传递的几种方式、外部符号与局部变量的概念和作用
基本理论:理解子程序的功能,会用主程序调用子程序,了解子程序调用和返回的现场保护的必要性,理解几种子程序调用涉及的参数传递方法,会用寄存器方式将子程序参数回送主调程序,理解PUBLIC和EXTRN伪操作的作用,熟悉堆栈方式下的参数传递过程
习题:
1、子程序定义的标准格式是:
   (A)…   PROC   ….         (B)…. PROC    ….
                  …                         ….
END                         ENDS            
      (C)   ….PROC….         
               ….                        
ENSP                                          
2、代码段内子程序调用和返回用到的指令及属性正确的是:
      (A) CALL FAR ;RET NEAR(B)CALL FAR;RET FAR (C)CALL NEAR ;RETS NEAR   (D)CALL NEAR;RET NEAR
                                                            
3、子程序定义及调用都可以嵌套。                  
                                                            (√)
4、参数调用过程中都必须使用传送工具是:
(A)地址表      (B)堆栈    (C)寄存器   (D)数据段   
5、子程序调用前需要对所有寄存器都进行压栈保存工作。         
                                                            (错)
页: [1]
查看完整版本: 大工13春《汇编语言程序设计》辅导资料十一