文档介绍:第六章子程序设计
§
、子程序
:完成某一总体功能或任务编制的程序,叫~。
(过程):仅能完成部分功能又可被多次调用的程序,叫~。
主程序和子程序的关系是相对的。主程序调用子程序的过程,称调用子程序(转子),用CALL指令实现。
子程序执行完后,应返回主程序的调用处,继续执行主程序,返回主程序(返主),用RET指令实现。
1 .简化程序设计过程,节省时间。
2. 缩短程序长度,节省空间。
3. 增加程序可读性,便于修改、调试。
4. 方便程序的模块化、结构化和自顶向下的程序设计。
§
一个完整的子程序由以下部分组成。
为了使编制的子程序具有一定的通用性,以便于调用,在子程序设计时,要建立子程序的说明文件(含:子程序名、功能、输入参数、输出参数、占用寄存器、示例等)
Ex:有一子程序说明文件如下
; 子程序名:DTOB
; 功能:完成将两位十进制数(BCD码)转换成二进制数
;输入参数:AL寄存器中存放要转换的十进制数
;输出参数:CL寄存器中存放转换后的二进制数
;所占用寄存器:BX
;示例:输入时 AL=01010110B
; 输出时 CL=00111000B
因为主、子程序分开编写,因此使用寄存器有可能冲突。
一般在子程序一开始保护子程序要占用的寄存器内容,子程序执行返回指令前再恢复这些被保护的寄存器的内容。
保护现场/恢复现场既可在主程序中完成,也可在子程序中完成,但通常在主(子)程序中保护现场,就一定在主(子)程序中恢复。
保护、恢复现场的方法:
、出栈恢复。
Ex: sub1 proc near
push ax
push bx
push cx
push dx
…
pop dx
pop cx
pop bx
pop ax
Ret
Sub1 endp
保护现场
恢复现场
,恢复现场再用数据传送指令,从指定的内存单元取回到对应的寄存器中。
Ex: buffer dw 10 dup(?)
…
sub1 proc near
lea di,buffer
mov [di],ax
mov [di+2],bx
mov [di+4],cx
mov [di+6],dx
…
lea si,buffer
mov ax,[Si]
mov bx,[Si+2]
mov cx,[Si+4]
mov dx,[Si+6]
ret
sub1 endp
子程序的调用CALL----在主程序中
子程序的返回 RET ----在子程序末尾
Call sub1
…..
Sub1 proc
…
ret
主程序
子程序
调用
返回
1. 子程序的调用
格式:CALL <子程序名>/<过程名>
根据调用程序和子程序是否在同一逻辑段,CALL指令分为段内、段间调用。
调用形式有:段内直接调用、段内间接调用、段间直接调用、段间间接调用。
(1) 段内直接调用
格式:Call DST
操作:(SP) (SP)-2
((SP)+1,(SP)) (IP)//下一条指令的地址,子程序的返回地址入栈
(IP) (IP)+D16//转移至子程序的入口地址
Ex: 1000:2540 call sub_proc
1000:2543 …
1000:3000 sub_proc
段内直接调用的一般表示方法:
CALL near ptr <标号>
或 call <标号>
将2543H压入栈,新的IP为3000H
(2) 段内间接调用
格式:Call DST
操作:(SP) (SP)-2
((SP)+1,(SP)) (IP)//下一条指令的地址,子程序的返回地址入栈
(IP) (EA) //EA可以是reg或mem中的内容.
EX: call word ptr [bx]
call si
call word ptr es:[si]
段内间接调用的一般表示方法:
CALL WORD ptr <标号>
或 call reg
(3)段间直接调用
格式:Call DST
操作:(SP) (SP)-2
((SP)+1,(SP)) (CS)
(SP) (SP)-2
((SP)+1,(SP)) (IP)//保护断点
(IP) 偏移地址//指令的第二、三字节(子程序的入口地址)
(CS) 段地址//指令的第四、五字节
EX: c1 segment
…
1000:2540 call far