子程序
子程序的概念:
在程序设计中,常常会遇到某些功能完全相同的程序段在同一程序的多处或不同程序中出现,为了节省存贮空间减少编制程序的重复劳动,可以将这些多次重复的程序段独立出来,附加一些额外语句,将它编制成一种具有公用性的,独立的程序段—子程序,并通过适当的方法把它与其他程序段链接起来,这种程序设计的方法称为子程序设计。
在汇编语言中,子程序又称过程;调用子程序的程序称为主调程序或主程序。
4.4.2子程序的格式:
子程序的定义是由过程定义伪指令PROC和ENDP来完成的.其格式如下:
(过程名) PROC [NEAR/FAR]
…
(过程名) ENDP
其中PROC表示过程定义开始,ENDP表示过程定义结束。过程名是过程入口地址的符号表示,可以在主程序直接用CALL (过程名)进行调用。
一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性。
4.4.3子程序的位置:
子程序可以在程序中的任何位置,一般情况下,子程序比较多的时候,将所有子程序放在代码段的开始位置,例如:
例4.16
;…………源程序…………
CODE SEGMENT
ASSUME CS:CODE
START:JMP MAIN;代码段开始位置,但是不是主程序开始位置
(过程名1) PROC
…
(过程名1) ENDP
(过程名2) PROC
…
(过程名2) ENPD
…
MAIN:…;主程序真正开始位置
…
CODE ENDS
END START
如果子程序比较少的时候,可以将子程序放在代码段的末尾处。
例4.17
;…………源程序…………
CODE SEGMENT
ASSUME CS:CODE
START:…
…
HLT;主程序结束位置
(过程名1) PROC
…
(过程名1) ENDP
CODE ENDS
END START
4.4.4主程序与子程序的参数传递:
主程序与子程序的参数传递的方式主要有:
1) 约定寄存器法
2)约定单元法
3)堆栈法(也称赋值法)
1.约定寄存器法
因为汇编语言可以对计算机硬件资源直接利用,当寄存器被赋值之后,其值一直保持不变,直到重新赋值为止,所以可以利用计算机的寄存器来传递参数。
这种方法是通过寄存器存放参数来进行传递的,即在主程序调用子程序前,将入口参数送到约定寄存器中;子程序可以直接从这些寄存器中取出参数进行加工处理,并将结果也放在约定的寄存器中,然后返回主程序,主程序再从寄存器中取出结果。
注意:约定寄存器法的特点是编程方便,速度快,节省存贮单元,但只适合参数较少的情况。
2.约定存贮单元法
这种方法是使用内存单元传递参数的,即在主程序调用子程序前,将入口参数存放到约定单元中;子程序执行结束将结果也放在约定单元。
注意:约定存贮单元法的特点是每个子程序都有独立的工作单元,工作时不易引起紊乱,但它占用了存贮空间,这种方法不适合递归子程序。
3.堆栈法
堆栈法是在紧接调用指令后面的一串单元中存放参数的。对于入口参数,一般是参数地址,当入口参数很少时,也可以是参数值.而对于出口参数一般是参数的值,当出口参数较多是也可以是地址。
注意:赋值法的特点是:入/出口参数包括在调用程序中,比较灵活,但在存取入/出口参数和修改返回地址时要特别仔细,当心出错。
4.4.5参数传递注意事项:
1.寄存器内容是否冲突:
因为寄存器是计算机硬件资源,而且使用比较频繁,一定要注意主程序与子程序、子程序之间在使用寄存器的时候有无冲突,如果有冲突的话可以利用堆栈先进行保护。
例4.18
若子程序PROG1中改变了寄存器AX,BX,CX,DX的值,则可采用如下方法保护和恢复现场。
;…………源程序…………
PROC1 PROC
PUSH AX
PUSH BX
PUSH CX;保护现场
PUSH DX
…;子程序的执行内容
POP DX
POP CX
POP BX;恢复现场
POP AX
RET;返回断点处
PROC1 ENDP
当然也可以在主程序调用子程序之前,在主程序中保存。
例4.19
;…………源程序…………
CODE SEGMENT
ASSUME CS:CODE
START:…
PUSH AX
PUSH BX
PUSH CX
PUSH DX
CALL PROC1
POP DX
POP CX
POP BX
POP AX
…
CODE ENDS
END START