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

子程序的嵌套

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





标签:

相关内容推荐: