您好,欢迎访问一九零五行业门户网

子程序的嵌套

一、子程序的嵌套
一个子程序作为调用程序去调用另一个子程序的情况称为子程序的嵌套。
嵌套深度:嵌套的层数称为嵌套深度。不受限制。
嵌套子程序的设计:没有什么特殊要求,除子程序的调用和返回应正确使用call和ret指令外,要注意寄存器的保护和恢复。如用堆栈传送数据要避免因堆栈使用中的溢出问题而造成子程序不能正确返回的错误。有两种可能发生堆栈溢出的情况:
堆栈上溢:如堆栈已满,但还想再存入信息,这种情况称为堆栈上溢。
堆栈下溢:如堆栈已空,但还想再取出信息,这种情况称为堆栈下溢。
递归子程序:子程序自己调用自己的情况称为递归调用,这种子程序称为递归子程序
二、嵌套深度
图1表示了嵌套深度为2时的子程序嵌套情况。
例1两个6字节数相加。
分析:将一个字节相加的程序段设计为子程序。主程序分3次调用该子程序,但每次调用的参数不同。
程序如下:
datasegment
add1dbfeh,86h,7ch,35h,68h,77h
add2db45h,bch,7dh,6ah,87h,90h
sumdb 6dup(0)
countdb6
dataends
stacksegment
db100dup(?)
stackends
codesegment
assume cs:code,ds:data,ss:stack
madd: mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov si,offset add1
mov di,offset add2
mov bx,offsetsum
mov cx,count;循环初值为6
clc
again:callsubadd;调用子程序
loop again;循环调用6次
mov ax,4c00h
int21h
;子程序入口参数:si,di,bx出口参数:si,di,bx
subadd proc;完成一个字节相加
push ax ;保护ax的值
mov al,[si];si是一个源操作数指针
adc al,[di];di是另一个源操作数指针
mov [bx],al;bx是结果操作数指针
incsi
incdi
incbx
popax ;恢复ax的值
ret
subadd endp
codeends
endmadd
例2把内存中的字变量number的值,转换为4个ascii码表示的十六进制数码串,串的起始地址为string。
分析:把内存中的字变量number的值,转换为4个ascii码表示的十六进制数码串的工作设计成一个子程序,在这个子程序中再调用另一个子程序,由它完成从bcd码到ascii码的转换。
程序如下:
datasegment
number dw25afh
stringdb 4dup(?),0dh,0ah,‘$’ 
dataends
codesegment
assume cs:code,ds:data
begin: mov ax,data
mov ds,ax
mov es,ax
lea bx,string
push bx ;将参数(结果地址指针)压入堆栈
push number;将源数据压入堆栈
call binhex ;调用子程序
lea di,string
mov ah,9
int21h
binhexproc 
push bp
mov bp,sp
push ax
push di
push cx
push dx
pushf;以上为保护现场
mov ax,[bp+4] ;取出number
mov di,[bp+6];取出string的偏移地址
add di,length string-1 ;使di指向转换数据
mov dx,ax;保护原始数据
mov cx,4
again: and ax,0fh ;取低4位
call hexd;调子程序
std
stosb;保护转换数据
push cx ;保护cx的值
mov cl,4
shrdx,cl
mov ax,dx
popcx
loop again
popf
popdx
popcx
popdi
popax
popbp
ret4
binhexendp
hexdproc ;将al中的bcd码转换成ascii码
cmp al,0ah
jladdz
add al,’a’-‘0’-0ah ;小写字母转换成ascii码,若为大写
addz: add al,‘0’ ;字母,则再加addal,7
ret
hexdendp
codeends
edn begin
例6.3 数的阶乘 1
按照阶乘的定义 n!=n*(n-1)!
这是一个递归定义式,可采用子程序的的递归调用形式。程序如下:
datasegment
numdb5
fnumdw?
dataends
stacksegment
db 100dup(?)
stackends
codesegment
assume cs:code,ds:data,ss:stack
begin: push ds
mov ax,0
push ax
mov cx,1
push cx
mov ah,0
mov al,num
call factor
mov fnum,ax
popcx
mov ax,4c00h
int21h
factorproc
cmp ax,0
jnziia
mov dl,1
ret
iia:push ax
dec al
call fact
iia1:popcx
mul cl ;callmult
iia2:mov dx,ax
ret
factorendp
codeends
end begin
其它类似信息

推荐信息