你的位置: 首页> 通信技术> 汇编语言

子程序的嵌套

2016-10-24 13:52:46 |人围观 | 评论:

一、子程序的嵌套

一个子程序作为调用程序去调用另一个子程序的情况称为子程序的嵌套。

嵌套深度:嵌套的层数称为嵌套深度。不受限制。

嵌套子程序的设计:没有什么特殊要求,除子程序的调用和返回应正确使用CALL和RET指令外,要注意寄存器的保护和恢复。如用堆栈传送数据要避免因堆栈使用中的溢出问题而造成子程序不能正确返回的错误。有两种可能发生堆栈溢出的情况:

堆栈上溢:如堆栈已满,但还想再存入信息,这种情况称为堆栈上溢。

堆栈下溢:如堆栈已空,但还想再取出信息,这种情况称为堆栈下溢。

递归子程序:子程序自己调用自己的情况称为递归调用,这种子程序称为递归子程序

二、嵌套深度

图1表示了嵌套深度为2时的子程序嵌套情况。

例1  两个6字节数相加。

分析:将一个字节相加的程序段设计为子程序。主程序分3次调用该子程序,但每次调用的参数不同。

程序如下:

DATA  SEGMENT

ADD1  DB  FEH,86H,7CH,35H,68H,77H

ADD2  DB  45H,BCH,7DH,6AH,87H,90H

SUM  DB     6DUP(0)

COUNT  DB  6

DATA  ENDS

STACK  SEGMENT

DB  100DUP(?)

STACK  ENDS

CODE  SEGMENT

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,OFFSET  SUM

MOV CX,COUNT  ;循环初值为6

CLC

AGAIN:CALL  SUBADD    ;调用子程序

LOOP   AGAIN      ;循环调用6次

MOV AX,4C00H

INT  21H

;子程序入口参数:SI,DI,BX    出口参数:SI,DI,BX

SUBADD PROC            ;完成一个字节相加

PUSH AX       ;保护AX的值

MOV AL,[SI]  ;SI是一个源操作数指针

ADC AL,[DI]  ;DI是另一个源操作数指针

MOV [BX],AL  ;BX是结果操作数指针

INC  SI

INC  DI

INC  BX

POP  AX   ;恢复AX的值

RET

SUBADD ENDP

CODE  ENDS

END  MADD

例2  把内存中的字变量NUMBER的值,转换为4个ASCII码表示的十六进制数码串,串的起始地址为STRING。

分析:把内存中的字变量NUMBER的值,转换为4个ASCII码表示的十六进制数码串的工作设计成一个子程序,在这个子程序中再调用另一个子程序,由它完成从BCD码到ASCII码的转换。

程序如下:

DATA  SEGMENT

NUMBER DW  25AFH

STRING  DB 4DUP(?),0DH,0AH,‘$’ 

DATA  ENDS

CODE  SEGMENT

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

INT  21H

BINHEX  PROC               

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

SHR  DX,CL

MOV AX,DX

POP  CX

LOOP AGAIN

POPF

POP  DX

POP  CX

POP  DI

POP  AX

POP  BP

RET  4

BINHEX  ENDP

HEXD  PROC                   ;将AL中的BCD码转换成ASCII码

CMP AL,0AH

JL  ADDZ

ADD AL,’a’-‘0’-0AH   ;小写字母转换成ASCII码,若为大写

ADDZ: ADD AL,‘0’         ;字母,则再加ADD  AL,7

RET

HEXD  ENDP

CODE  ENDS

EDN BEGIN

例6.3   数的阶乘                   1

按照阶乘的定义         n!=    n*(n-1)!

这是一个递归定义式,可采用子程序的的递归调用形式。程序如下:

DATA  SEGMENT

NUM  DB  5

FNUM  DW  ?

DATA  ENDS

STACK  SEGMENT

DB   100DUP(?)

STACK  ENDS

CODE  SEGMENT

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

POP  CX

MOV AX,4C00H

INT  21H

FACTOR  PROC

CMP AX,0

JNZ  IIA

MOV DL,1

RET

IIA:  PUSH AX

DEC AL

CALL FACT

IIA1:  POP  CX

MUL CL   ;CALL  MULT

IIA2:  MOV DX,AX

RET

FACTOR  ENDP

CODE  ENDS

END BEGIN





标签:

相关内容推荐: