第07章-1 子程序设计与多模块编程_第1页
第07章-1 子程序设计与多模块编程_第2页
第07章-1 子程序设计与多模块编程_第3页
第07章-1 子程序设计与多模块编程_第4页
第07章-1 子程序设计与多模块编程_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第七章子程序设计与多模块编程7.1子程序的引出7.2子程序(过程)定义伪指令7.3调用和返回指令7.4子程序设计方法7.5子程序嵌套7.6递归子程序7.7可重入子程序7.8程序的连接7.1子程序的引出在我们编写解决实际问题的程序时,往往会遇到多处使用相同功能的程序段,使用该程序段的唯一差别是对程序变量赋不同的值,例如计算:S=√2X+√3Y+√150计算上述函数需要多次使用开方运算,如果每次用到开方运算就编写一段开方程序,那末开方程序在程序中会多次出现,不仅书写麻烦,容易出错,编辑、汇编它时,也会花费较多时间。同时,由于冗长,占用内存也较多。如果把多次使用的功能程序编制为一个独立的程序段,每当用到这种功能时,就将控制转向它,完成功能后再返回到原来的程序,这就会大大减少编程工作量。7.1子程序的引出

使用子程序的好处:(1)简化了程序设计过程,减少了工作量,节省了时间;(2)源程序缩短,节省了机器汇编源程序的时间和存储目标代码的存储空间;(3)增加了源程序的可读性,便于调试维护;(4)有利于程序模块化、结构化和自顶向下的程序设计;(5)子程序一旦编制成功,在开发研制各种软件时都可利用,大大缩短了软件的开发周期。7.1子程序的引出

子程序设计需了解的问题:1.子程序的定义与调用设计出可以完成相对独立功能的程序段,并对汇编程序提供必要的信息,使得对该程序段汇编之后,在需要时可以被其他主程序调用,这一过程称为子程序的定义。已定义的子程序在什么时候被执行,执行多少次,都不是由子程序自身决定的。在主程序需要调用相应的子程序时,可以用调用子程序指令使得相应子程序被执行。2.主程序与子程序之间的调用与返回在主程序需要利用子程序的执行来完成某种工作时,就可以使用调用子程序指令来调用相应的子程序;在子程序完成它应该完成的工作之后,应当用返回指令返回调用它的主程序。主程序::CALLSUBR::子程序SUBR:::::RET7.2子程序(过程)定义伪指令子程序定义伪指令所定义的子程序的一般格式:PNPROC[NEAR]/[FAR];说明过程开始:;过程体:RETPNENDP;说明过程结束7.3调用和返回指令1.调用分类(1)段内调用与段间调用段内调用:转返地址只用IP实现;段间调用:转返地址由CS和IP实现。(2)直接调用与间接调用直接调用:调用指令使用过程名调用过程,过程的指令入口地址偏移量直接送入IP来实现。间接调用:调用指令通过某寄存器或某存储器单元指出被调用程序的入口地址。2.调用指令

指令汇编格式:CALLPROCNAME/REGNAME/MEMLABEL

操作:(1)段内调用:SP←SP-2(SP+1,SP)←IPIP←OFFSETPROCNAME或REGNAME或(MEMLABEL)

(2)段间调用:SP←SP-2(SP+1,SP)←CSCS←SEGPROCNAME或(MEMLABEL+2,MEMLABEL+3)SP←SP-2(SP+1,SP)←IPIP←OFFSETPROCNAME或(MEMLABEL,MEMLABEL+1)受影响的寄存器:没有3.返回指令指令汇编格式:RET[VAL]操作:(1)段内返回:IP←(SP+1,SP)SP←SP+2SP←SP+VAL(如果选用了VAL)

(2)段间返回:IP←(SP+1,SP)SP←SP+2CS←(SP+1,SP)SP←SP+2SP←SP+VAL(如果选用了VAL)受影响的寄存器:没有7.4子程序设计方法7.4.1现场的保护和恢复7.4.2子程序说明文件7.4.3主程序与子程序之间的参数传递7.4.1现场的保护和恢复子程序中需要使用的寄存器,有可能在主程序中正被用来保存某种中间结果,这些寄存器的值在从子程序返回主程序后还要继续使用,这些寄存器的值或所需的标志位的值等信息称之为现场。显然,子程序执行前需要保护现场,返回时要恢复现场。保存现场与恢复现场的工作既可在调用程序中完成,也可在子程序中完成,程序设计时根据情况安排。如果子程序已经设计好了,而其中未保护主程序现场,那么调用程序在使用子程序之前应保护现场,从子程序返回后再恢复现场。通常在主程序中保护现场,则一定在主程序中恢复;在子程序中保护现场,则一定在子程序中恢复。这样可以增强主程序和子程序之间的相对独立性,减少相互依赖,使程序结构清楚,减少错误。7.4.1现场的保护和恢复保护现场和恢复现场的方法:(1)利用压栈和出栈指令,将寄存器内容或状态标志位内容保存在堆栈中,恢复时再从堆栈中取出。例子:

SQROOT1PROC NEARPUSHAX ;保存现场PUSHBXPUSHCX... ;子程序正常工作POPCX ;恢复现场POPBXPOPAXRETSQROOT1ENDP(2)利用内存单元。用传送指令将寄存器的内容保存到指定的内存单元,恢复时再用传送指令取出。7.4.2子程序说明文件(1)子程序名(子程序入口地址):用过程(子程序)定义伪指令定义该过程(子程序)时的过程名,这时过程(子程序)中第一条语句必须是子程序的入口指令;否则应写子程序入口指令的标号或地址。(2)子程序功能:用自然语言或数学语言等形式简单清楚地描述子程序完成的任务。(3)入口条件:说明子程序要求有几个入口参数,这些参数表示的意义及存放位置。(4)出口条件:说明子程序有几个输出参数(运行结果),这些参数表示的意义、存放的位置。(5)受影响的寄存器:说明子程序运行后,哪些寄存器的内容被破坏了,以便使用者在调用该子程序之前注意保护现场。7.4.2子程序说明文件子程序说明文件例子:(1)子程序名:SQROOT1;(2)程序功能:求双字节整数的平方根的整数部分;(3)入口条件:被开方数放在DX中;(4)出口条件:平方根在DX中;(5)受影响的寄存器:AX,BX,CX,DX及标志寄存器F。7.4.3主程序与子程序之间的参数传递子程序运行时所需的加工对象应由调用程序提供,处理的结果应提供调用程序使用,二者之间要进行信息交换或者说相互之间要传递参数。常用的传送方法有四种:(1)约定寄存器法;(2)约定存储单元法;(3)堆栈法;(4)约定参数地址指针法。以计算下述函数为例,说明各种参数传送方法。

例7.1编制程序计算:Z=√2X+√3Y+√150设X,Y为整数字数据,且存于PX和PY单元,计算结果存入RLT单元。1.约定寄存器法

约定寄存器法传送参数,即事先约定一些存放参数的通用寄存器,调用程序转向子程序时,先把要传送的参数放到约定好的寄存器中,子程序工作时,从约定的寄存器中取参数,然后把结果存入事先约定的寄存器中,调用程序再从约定的寄存器中取结果。这种方法是程序设计中最常用、最简单、最方便的方法,在传送参数不多的情况下都采用此方法。1.约定寄存器法

开平方子程序和调用程序,约定将被开平方数放在DX中,平方根也放在DX中,其结果求得平方根的整数部分。1:;*****EXAM7.1.1S*****2:SQROOT1 PROC NEAR3: XOR AX,AX ;i←04: AND DX,DX ;测试被开方数5: JZ SQRT2 ;被开方数为06:SQRT1: MOV BX,AX ;形成奇数7: SHL BX,18: INC BX9: SUB DX,BX ;被开方数减去奇数10: JC SQRT2 ;不够减11: INC AX ;够减,i增112: JMP SQRT1 ;继续13:SQRT2: MOV DX,AX ;DX←平方根14: RET ;返回15:SQROOT1 ENDP1.约定寄存器法调用程序:1:;*****EXAM7.1.1M*****2:SSEGSEGMENTSTACK3:STKTOPDB20DUP(0)4:SSEGENDS5:DSEGSEGMENT6:PXDW123457:PYDW24698:RLTDW09:DSEGENDS10:CSEGSEGMENT11:ASSUMECS:CSEG,DS:DSEG12:ASSUMESS:SSEG13:MAIN1:MOVAX,DSEG14:MOVDS,AX15:MOVAX,SSEG16:MOVSS,AX

17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤初始态(执行指令①后)17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤执行指令②后17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤执行指令RET后17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤执行指令③后17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤执行指令④后17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤执行指令RET后17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X20: CALL SQROOT1 ;调用开平方子程序21: PUSH DX ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX26: CALL SQROOT1 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,15031: CALL SQROOT132: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END MAIN1SQROOT1 PROC NEAR XOR AX,AX AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV DX,AX RETSQROOT1 ENDP①②③④⑤执行指令⑤后2.约定存储单元法

约定存储单元法传送参数,与约定寄存器法类似。下面设计的开平方子程序与调用程序,约定被开方数放在ARGX单元,计算结果放入ROOT单元。1:;*****EXAM7.1.2S*****2:SQROOT2 PROC NEAR3: XOR AX,AX ;i←04: AND DX,DX ;测试被开方数5: JZ SQRT2 ;被开方数为06:SQRT1: MOV BX,AX ;形成奇数7: SHL BX,18: INC BX9: SUB DX,BX ;被开方数减去奇数10: JC SQRT2 ;不够减11: INC AX ;够减,i增112: JMP SQRT1 ;继续13:SQRT2: MOV DX,AX 14: RET ;返回15:SQROOT2 ENDPMOVDX,ARGXMOVROOT,AX17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X MOV ARGX,DX20: CALL SQROOT2 ;调用开平方子程序21: PUSH ROOT ;暂存结果√2X22: MOV DX,PY ;取Y23: MOV AX,DX ;计算3Y24: ADD DX,DX25: ADD DX,AX MOV ARGX,DX26: CALL SQROOT2 ;调用开平方子程序27: POP AX ;取出√2X28: ADD AX,ROOT ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV ARGX,15031: CALL SQROOT232: POP AX ;取出中间结果33: ADD AX,ROOT ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN1SQROOT2 PROC NEAR XOR AX,AX MOV DX,ARGX

AND DX,DX JZ SQRT2SQRT1: MOV BX,AX SHL BX,1 INC BX SUB DX,BX JC SQRT2 INC AX JMP SQRT1SQRT2: MOV ROOT,AX RETSQROOT2 ENDP3.堆栈法

堆栈法传送参数是调用程序先将参数压入堆栈,子程序从堆栈中把参数取出,进行处理,然后把结果压入堆栈,调用程序再从堆栈中取出结果。1:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4: INC SP5: POP DX6: XOR AX,AX ;i←07: AND DX,DX ;测试被开方数 . . .13:SQRT2: PUSH AX14: DEC SP15: DEC SP 16: RET ;返回17:SQROOT3 ENDP17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22: MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4: INC SP5: POP DX6: XOR AX,AX 7: AND DX,DX . . .13:SQRT2: PUSH AX14: DEC SP15: DEC SP 16: RET ;返回17:SQROOT3 ENDP初始态(执行指令①后)17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22: MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令②后17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22:xxyy MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令③后17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22:xxyy MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令⑧后17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22:xxyy MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令⑨后17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22:xxyy MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令㈠后17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22:xxyy MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令㈡后17:①MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X② PUSH DX20:③ CALL SQROOT3 22:xxyy MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX④ PUSH DX26:⑤ CALL SQROOT3 ⑥ POP DX27:⑦ POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT3 PROC NEAR3: INC SP4:⑧ INC SP5:⑨ POP DX6: XOR AX,AX 7: AND DX,DX . . .13:㈠SQRT2: PUSH AX14: DEC SP15:㈡ DEC SP 16: RET ;返回17:SQROOT3 ENDP执行指令RET后17:MOVSP,SIZESTKTOP18: MOV DX,PX ;取X19: ADD DX,DX ;计算2X PUSH DX20: CALL SQROOT3 22:XXYY MOV DX,PY 23: MOV AX,DX 24: ADD DX,DX25: ADD DX,AX PUSH DX26: CALL SQROOT3 POP DX27: POP AX 28: ADD AX,DX ;计算√2X+√3Y29: PUSH AX ;暂存结果30: MOV DX,150 PUSH DX31: CALL SQROOT3 POP DX32: POP AX ;取出中间结果33: ADD AX,DX ;计算最终结果34: MOV RLT,AX ;保存结果35: MOV AH,4CH36: INT 21H37:CSEG ENDS38: END

MAIN11:;*****EXAM7.1.3S*****2:SQROOT4 PROC NEAR3: PUSH BP4: MOV BP,SP5: MOV DX,[BP+4]6: XOR AX,AX 7: AND DX,DX . . .13:SQRT2: MOV[BP+4],AX14: POP BP15: RET ;返回16:SQROOT4 ENDP执行指令RET后4.约定参数地址指针法当要传送的参数较多时,用约定地址指针法,即调用程序将参数存放的地址送入约定的地址指针,然后调用子程序,子程序从地址指针指出的地址取出所需参数。当返回参数较多时,可存入内存某区域,然后把其首地址指针放入约定的寄存器中,供调用程序使用。例8.2设内存有三组无符号字整数,三组数据的首地址分别为LIST1,LIST2和LIST3,数据个数分别存放在CNT1,CNT2和CNT3单元。编制程序计算三组数据中最小数之和并存入SUM开始的单元。求一组数据中最小数据的子程序1:;*****EXAM7.2S*****2:FMIN PROCNEAR;求数组中最小值3:PUSHSI;保存数组首址4:MOVAX,[SI];取第一个数5:DECCX;计数值减16:JZRETURN;计数值为0,转7:FMIN2:INCSI;修改数组指针8:INCSI9:CMPAX,[SI];与下一个数比较10:JBFMIN1;AX中数小,转11:MOVAX,[SI];小数取入AX12:FMIN1:LOOPFMIN2;计数值减1,不为0转13:RETURN:POPSI;恢复数组首值14:RET;返回15:FMINENDP1:;*****EXAM7.2M*****2:SSEG SEGMENTSTACK3:SKTOPDB40DUP(0)4:SSEGENDS5:DSEGSEGMENT6:LIST1DW35,27,165,3,1825,6037:CNT1DW68:LIST2DW438,121,496,6321,28,17,2,1059:CNT2DW810:LIST3DW18,5,19,46,372511:CNT3DW512:SUMDW013:DSEGENDS14:CSEGSEGMENT15:ASSUMECS:CSEG,DS:DSEG16:ASSUMESS:SSEG17:MAIN:MOVAX,DSEG18:MOVDS,AX19:MOVAX,SSEG20:MOVSS,AX21:MOVSP,LENGTHSKTOP22:MOVSI,OFFSETLIST123:MOVCX,CNT124:CALLFMIN25:MOVBX,AX26:MOVSI,OFFSETIST227:MOVCX,CNT228:CALLFMIN29:ADDBX,AX30:MOVSI,OFFSETLIST331:MOVCX,CNT332:CALLFMIN33:ADDBX,AX34:MOVSUM,BX35:MOVAH,4CH36:INT21H37:CSEGENDS38:ENDMAIN子程序设计的举例例7.3计算三组字数据中正数、负数和零的个数,并分别存入PCOUNT,MCOUNT和ZCOUNT单元。设三组数据首地址分别ARRY1,ARRY2和ARRY3,数据个数分别在CNT1,CNT2和CNT3单元存放。子程序说明文件如下:(1)子程序名(入口标号):PMZN;(2)子程序功能:求一组数据中正数、负数和零的个数;(3)入口条件:数组首地址在SI中;数组数据个数在CX中;(4)出口条件:正数个数在AX中;负数个数在BX中;零的个数在DX中;(5)受影响的寄存器:AX,BX,DX和标志寄存器F。;*****EXAM7.3S***** PUBLIC PMZNCSEGSEGMENT ASSUMECS:CSEGPMZNPROCFAR PUSHSI ;保存数组首址 PUSHCX ;保存数据个数 XORAX,AX ;清计数器 XORBX,BX XORDX,DXPMZN0:TESTWORDPTR[SI],0FFFFH ;测试数据 JSMINUS ;负转 JNZPLUS ;非0转 INCDX ;为0,0计数器加1 JMPPMZN1PLUS:INCAX ;正数计数器加1 JMPPMZN1MINUS:INCBX ;负数计数器加1PMZN1:ADDSI,2 ;指向下一个数据 LOOPPMZN0 ;循环计数减1,非0转 POPCX ;恢复CX POPSI ;恢复SI RETPMZNENDPCSEGENDS END;*****EXAM7.3.M***** EXTRN PMZN:FARSSEGSEGMENTSTACKSKTOPDB50DUP(0)SSEGENDSDSEGSEGMENTARRY1DW15,-5,1,5,0,123,964,-327,0CNT1DW9ARRY2DW103,4,-8,-23,0,827,-936,0,0,18CNT2DW10ARRY3DW-29,-137,-23,0,4,0CNT3DW6PCOUNTDW0 ;保存结果单元MCOUNTDW0ZCOUNTDW0ADRDWOFFSETARRY1,OFFSETCNT1 DWOFFSETARRY2,OFFSETCNT2 DWOFFSETARRY3,OFFSETCNT3DSEGENDSCSEGSEGMENT ASSUMECS:CSEG,DS:DSEG ASSUMESS:SSEGSTART:MOVAX,DSEG MOVDS,AX MOVAX,SSEG MOVSS,AX MOVSP,LENGTHSKTOP

LEADI,ADR MOVCX,03AGAIN:MOVSI,[DI] ;取数组首址→SI MOVBX,[DI+2] ;取数组数据个数首址 PUSHCX ;保存CX中的循环计数值 MOVCX,[BX] ;取数组数据个数→CX CALLFARPTRPMZN ADDPCOUNT,AX ;累加结果 ADDMCOUNT,BX ADDZCOUNT,DX ADDDI,4 ;修改指针指向下一数组 POPCX ;恢复CX中循环计数 LOOPAGAIN ;CX计数值减1,非0转 MOVAH,4CH INT21HCSEGEND ENDSTART7.5子程序嵌套我们编制子程序时,如果用到已有的某种功能的子程序,也可以采用调用的方法,在一个子程序的内部再调用其它子程序,称为子程序嵌套。这样的子程序称为嵌套子程序。嵌套子程序的层数称为嵌套深度,一般设有硬件堆栈的计算机,嵌套深度只受堆栈区大小的限制。假设我们已经有一个子程序,其说明文件和程序清单如下:(1)子程序名:HTOA;(2)子程序功能:将一位十六进制数转换为ASCII码;(3)入口条件:要转换的数据在AL中的低四位;(4)出口条件:十六进制数的ASCII码在AL中;(5)受影响的寄存器:AL和标志寄存器F。程序清单如下:;*****EXAM7.4S3*****HTOA PROC NEARANDAL,0FH CMPAL,10 JCHTOA1 ADDAL,07HTOA1:ADDAL,30H RETHTOAENDP(1)子程序名:BHTOA;(2)子程序功能:将两位十六进制数转换为ASCII码;(3)入口条件:两位十六进制数在AL中;(4)出口条件:高位十六进制数的ASCII码在AH中;低位十六进制数的ASCII码在AL中;(5)受影响的寄存器:AX和标志寄存器F。;*****EXAM7.4S2*****BHTOA PROC PUSHCX MOVCH,AL MOVCL,04 SHRAL,CL CALLHTOA MOVAH,AL MOVAL,CH CALLHTOA POPCX RETBHTOA ENDP

假定在内存DATA单元存放着一个无符号的字节数据,将它在屏幕上显示出来。DSEG SEGMENTDATA DB 4CHDSEG ENDSCSEG SEGMENT ASSUME CS:CSEG,DS:DSEGSTART:MOV AX,DSEG MOV DS,AX MOV AL,DATA CALL BHTOA PUSH AX MOV DL,AH MOV AH,2 INT 21H POP DX INT 21H MOV AX,4C00H INT 21HCSEG ENDS END START7.6递归子程序子程序能直接或间地调用自身称为递归调用,具有递归调用性质的子程序称为递归子程序。递归子程序一般用于解递归函数,递归函数定义具有下述两个组成部分:1.递归函数的递归过程必须是有限的。即每个递归函数有一个非递归终值,递归过程(子程序)一旦求得该值,就结束递归。2.任一函数项的值都有明确的定义,其值可由函数中的一项或几项值求得。

举例:阶乘函数,对于任一个大于等于0的正整数N,其函数值定义为:1(N=0)FACT(N)=

N*FACT(N-1)(N>0)

{算法(1)测试N=0吗?是,则令FACT(N)=1,返回;(2)保存N,并令N=N-1,调用自身求得FACT(N-1);(3)顺序取出保存的N值(后保存的先取出);(4)计算FACT(N)=N*FACT(N-1),并返回。1:;*****EXAM7.5S*****2:FACT PROC NEAR3:ANDBX,BX4:JZ FACT15:PUSHBX6:DECBX7:CALLFACT8:F:POPBX9:MULBX10:RET11:FACT1:MOVAX,112:RET13:FACTENDP举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1 PUSH BX DEC BX CALL FACTaabb POP BX MUL BX RETFACT1: MOV AX,1 RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN执行指令①后举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN执行指令②后BX=4AX=?SP=1EH举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN执行指令③后BX=4AX=?SP=1CH举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN执行指令④后BX=3AX=?SP=1AH举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN再执行指令③后BX=3AX=?SP=18H举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN再执行指令④后BX=2AX=?SP=16H举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy NOPCSEG ENDS END MAIN再执行指令③后BX=2AX=?SP=14H举例:求4!SSEG SEGMENTSKTOP DB 20HDUP(0)SSEG ENDSCSEG SEGMENT ASSUMECS:CSEGFACT PROC NEAR AND BX,BX JZ FACT1③ PUSH BX DEC BX④ CALL FACTaabb POP BX MUL BX⑤ RETFACT1: MOV AX,1⑥ RETFACT ENDPMIAN: MOV AX,SSEG MOV DS,AX① MOV SP,SIZESKTOP MOV BX,4② CALL FACTxxyy

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论