子程序的基本结构包括以下几个部分:
(1)子程序定义
(2)保护现场和恢复现场
(3)子程序体
(4)子程序返回
子程序的定义:
子程序的定义是由过程定义伪指令PROC和ENDP来完成的。其格式如下:
过程名 PROC [NEAR/FAR]
┆
过程名 ENDP
其中PROC表示过程定义开始,ENDP表示过程定义结束。过程名是过程入口地址的符号表示。
一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性(NEAR 和 FAR)。
子程序的调用和返回:
如果调用程序和过程在同一代码段中,则使用NEAR属性
如果调用程序和过程不在同一代码段中,则使用FAR属性
保护现场和恢复现场:
例如:若子程序PROG中改变了寄存器AX,BX,CX,DX的值,则可采用如下方法保护和恢复现场。
SUB PROC NEAR
PUSH AX
PUSH BX
PUSH CX ;保护现场
PUSH DX
┆ ;子程序功能主体
POP DX
POP CX
POP BX ;恢复现场
POP AX
RET ;返回断点处
PROC ENDP
主程序与子程序参数传递方式:
1 寄存器传送参数
寄存器传递由主程序将要传递的参数装入事先约定的寄存器中,转入子程序后再取出进行处理,这种方法受CPU内部寄存器数量限制,因此只适于传递少量参数的场合,如一些常见的软件延时子程序,均是利用某寄存器传递循环计数器初值.
2. 共享存储单元
它是在内存中开辟特定的一片区域用于传递参数.主程序和子程序都按事先约定在指定的存储单元中进行数据交换,这种方法要占用一定数量的存储单元.不足之处是信息易被修改,不利于模块化设计.
3 通过堆栈传递地址或参数
通过堆栈实现参数传递这种方法是先在主程序中把参数和参数地址压入堆栈,在子程序中取出使用,由于堆栈操作不占用寄存器,并且堆栈单元使用后可自动释放,反复使用,便于实现数据隔离和模块化设计.使用这种方法时,当子程序返回后,这些参数就不在有用了,应当丢弃.这时可以利用带立即数的返回指令修改指针,使其指向参数入栈以前的值.