子程序
子程序的定义及使用

表达式实际上都可表示成一元、二元或多元函数关系,即 F(x1,x2,…,xn),这些函数关系如果没有对应的标准函数,则 需要用户设法定义新的函数来实现它们。
FORTRAN 90提供了语句函数定义功能来定义一些简单的 函数,用于实现有关的函数关系。用户自定义语句函数其使 用方法与标准函数相同,可以作为操作数在表达式中调用。
DB=F(x,y,z,y) DG=F(x,y,z,z) WRITE(*,*) DA,DB,DG
END program
9.3 外部函数子程序
无法用一条语句来定义的函数,可以用一个单独的 程序单位定义,它不属于调用函数语句所在的程序 单位,因此称之为外部函数。
是用户自定义的函数子程序。所在程序的其他程序 单位都可以调用它。
SUBROUTINE add(m,n,s) INTEGER m,n,s s=m+n m=m+1
END SUBROUTINE add
外部子例行程序,简称外部子程序,也称外部过程,是 独立的程序单元。
外部子例行程序可产生多个结果,由参数返回。 外部子例行程序定义一般格式:
<外部子例行程序定义>→
函数引用、外部函数引用以及外部函数名和子程序名等。 如果定义外部函数无形式参数,其引用形式为:F( )。 外部函数执行过程:
若实在参数为表达式,则先对表达式求值。 实在参数与相应的形式参数结合,将实参值传递给对应形参。 经过形实结合,形式参数获得了所需要的值,然后,立即执
行内部函数体。 在 执 行 函 数 体 的 过 程 中 , 若 遇 到 RETURN 语 句 或 END
F(x1,x2,x3)=3.14159*(x1+x2/60.0+x3/3600.0)/180.0 A=F(36.0,43.0,27.0) B=F(15.0,24.0,0.0) C=F(8.0,16.0,54.0) S=COS(A)**2-4*SIN(B)*TAN(C) WRITE (*,*) A,B,C,S
使用子程序的注意事项

1.编写子程序时,一般采用增量方式编程,这样可减少计算量。
2.主程序中的模态指令可被子程序中同一组的其他G 代码所更改。
如子程序用了G91代码后,再返回主程序时将继续以G91方式进行,故应特别注意代码的转换,否则可能产生位置错误。
3.调用程序时使用刀补。
最好不要在刀具补偿状态下的主程序中调用子程序,换句话来说,刀补的建立和取消应在子程序进行。
如果必须在主程序中建立,则应在主程序中消除。
绝不能在主程序中建立,在子程序取消,也不能在子程序建立,在主程序中消除,否则极易出错。
4.子程序不能单独运行。
汇编语言——子程序

6.2.2.2 RET指令 指令 【指令格式】RET 【功能】这是子程序返回指令,必须写在子程序的指令 序列之中。根据所在的子程序的类型不同,RET指令的功能 也分为两种情况: (1)如果RET所在子程序是NEAR类型,则从堆栈中出 栈一个字(当然,SP会加2),送给IP。 (2)如果RET所在子程序是FAR类型,则先从堆栈中出 栈一个字送到IP,再出栈一个字送到CS,栈顶指SP的值加4。
cr
PROC NEAR MOV AH,2 MOV DL,13 INT 21H MOV DL,10 INT 21H RET
cr ENDP main:MOV AX,dseg MOV DS,AX LEA DX,buf MOV AH,10 INT 21H CALL cr MOV AH,1 INT 21H MOV BL,AL ;输入一个字符 ;用BL保存读入的字符 ;输入一个符号串
【解】程序段(a)中,先把AX赋值为102H,再把BX赋 值为304H,然后用ADD指令把两数相加,和为406H,结果 放在ADD指令的目的操作数AX中。 程序段(b)的前两行与(a)完全相同,AX取值102H,BX 取值304H,但在相加之前调用了子程序cr。从例6.3中cr的 具体实现方法可以知道,调用过程中寄存器AH的值被改为 2,因为INT 21H输出功能,使AL的值也被修改,变成0AH, 并且这个值一直保持到调用结束,于是“CALL cr”指令调 用子程序后,AX的值不再是调用前的102H,而变成了 20AH,当ADD指令进行两个寄存器相加时,结果是50EH, 并放到目的操作数AX中。
6.3 应用子程序进行编程
6.3.1 子程序实例
【例6.3】分析下列程序,描述它的功能。 dseg SEGMENT buf DB 80,81 DUP(0) dseg ENDS sseg SEGMENT STACK DW 64 DUP(0) sseg ENDS cseg SEGMENT ASSUME CS:cseg,DS:dseg,SS:sseg
第十一节 子程序的调用

• 该程序的功能是什么?子程序的入口参数和出口参数分别存 该程序的功能是什么? 放在哪个寄存器中?子程序最后还有的一条指令是什么? 放在哪个寄存器中?子程序最后还有的一条指令是什么?
思考题
• • • 调用子程序及返回与堆栈无关。 ( )调用子程序及返回与堆栈无关。 ( )一段子程序可以被主程序多次调 用。 主程序调用子程序时是怎样确保返回主 程序调用指令后的断点位置, 程序调用指令后的断点位置,以便在断 点处继续执行主程序? 点处继续执行主程序?
第十节 子程序的调用
子程序的概念
• 子程序是一种重要的程序结构。 在实用中, 子程序是一种重要的程序结构 。 在实用中 , 常会遇到需要反复多次执行同一程序段的情 为了减少重复编写的工作量, 形 。 为了减少重复编写的工作量 , 并减少程 序存储空间, 常常把功能完整、 序存储空间 , 常常把功能完整 、 意义明确并 次使用的程序段从原来的程序( 被多次使用的程序段从原来的程序(称为主程 中分离出来独立编写,就成为子程序, 序)中分离出来独立编写,就成为子程序,从 而主程序可根据需要多次调用子程序。 而主程序可根据需要多次调用子程序。
寄存器或存储器法举例 寄存器或存储器法举例
•
• • • • • • • • • • • • • • • •
MAIN: MOV R0,#29H : , MOV R2 ,#06H MOV R3,#09H , ACALL JIAFA MOV A,R7 , MOV @R0,A , MOV R2,#25H , MOV R3,#45H , ACALL JIAFA MOV A,R7 , MOV @R0,A , …… JIAFA:MOV A,R2 : , ADD A,R3 , MOV R7,A , INC R0 。
子程序

子程序是一个为实现某个功能的独立程序。 其特点是:
它总被其它程序调用而一般不能单独执行。通
常把调用它的程序称为主程序,被主程序调用 的程序称为子程序。当然,其概念也是相对的, 即子程序也可以调用其他子程序。
主程序与子程序的调用关系
主程序Main.prg 子程序Sub.prg
…… Do Sub …… Return
2.带参数过程的调用
若要给过程中形式参数传递数据,必须在主程序中将实际参数包 含在过程的调用命令中,带有参数的过程调用的命令格式为: 格式: DO 〈过程名〉 WITH 〈实际参数表〉 功能: 将〈实际参数表〉中的内容传递给指定〈过程名〉相对应的形式 参数表,然后执行该过程。 说明: Ⅰ 〈实际参数表〉中的参数必须与PARAMETER语句中定义的 形式参数变量表的数量、类型与次序上完全一致。 Ⅱ 〈实际参数表〉中的参数可以是常量、变量和表达式,各个参 数间用“,”分隔。
&& 定义函数名AREA && 定义函数的形参 R && 返回函数的值
习题:写一个求任意数阶层的函 数,在主程序中调用该函数求任 意三个数的阶层之和 (S=A!+B!+C!)
10.5 参数的传递
无论是过程、还是自定义函数,参数传递都是一个 非常重要的概念。 传递参数: Do <子程序名/过程名> with <实际参数表> 说明:写在主程序中。 接受参数: Parameters <形式参数表> 说明:写在过程(或者函数等)中。
例1:编写一个求1到N的累加和的过程,并在过程中输出和。 clear input "input n:" to x do leijia with x Return procedure leijia parameters n sum=0 for i=1 to n sum=sum+i endfor ?sum return
子程序

3、调用子程序M98指令
格式: M98
P --- ---- ;
子程序名
调用次数 (1-999)
4、子程序结束M99指令
格式: M99 功能:执行到子程序结束M99指令后,
返回主程序 。
五、子程序的格式
OXXXX; …… …… …… …… M99;
例题
程序
• O1;(主程序) • G91G28Z0; • T01M06; • G90G54G00X70.Y0; • G43H01Z20.S1000M03; • G01Z0; • M98P30002; • G00Z20. • G49G91G28Z0; • M05M3一步简化程序,可以让子程序调用 另一个子程序,这种程序的结构成为子程序嵌套。 在编程中使用较多的是二重嵌套,其程序的执行 情况如图:
2、子程序的应用:
(1)零件上若干处具有相同的轮廓形状:在这种 情况下,只要编写一个加工该轮廓形状的子程序, 然后用主程序多次调用该子程序的方法完成对工 件的加工。 (2)加工中反复出现具有相同轨迹的走刀路线: 如果相同轨迹的走刀路线出现在某个加工区域或 在这个区域的各个层面上,采用子程序编写加工 程序比较方便,在程序中常用增量值确定切入深 度。
• 02;(子程序) • G91G01Z-5.; • G90G41D01G01X25.Y0; • G01X25.Y-15.; • G02X15.Y-25.R10.; • G01X-25.Y-25.; • G01Y15.; • G02X-15.Y25.R10.; • G01X25.Y25.; • G01X25.Y0; • G40G01X70.Y0; • M99;
Fanuc-0i加工中心编程
子程序调用指令
子程序调用指令
子程序的调用

mov ax,data mov ds,ax call nearp lea ax,nearp call ax call nproc lea bx,nproc call word ptr [bx]
call farp call fproc lea bx,fproc
Nearp proc near
…… ret Nearp endp Code1 ends end main code2 segment
3)在调用时,NEAR 和FAR 可以强制改变 CALL FAR PTR NEARPROC CALL NEAR PTR FARPROC
子过程的调用与返回指令
子过程的调用是个”有去有回”的过程,子程序执行
完后必须返回CALL指令的下一条指令处,因此必须对
CALL指令的下条指令的地址进行保存.保存地址的操作 是通过堆栈来完成.不是采用PUSH \POP指令来实现,而
通过存储器来传递参数
当调用程序和子程序处于同一文件中,可以直接访问 块内的变量或数据。 举例3:编写程序从键盘上输入一个字符串,存于变量为INPUT中, 要求以回车键作为输入过程的结束,字符结尾部分添加0。 (1) 分析: 子程序getstring直接从键盘输入字符串,入口参数:无。出 口参数:字符串变量INPUT 变量INPUT 属于通过存储器传递参数,调用程序和子程序处 于同一文件在数据段定义变量属于局部变量
Findmax proc
mov ax,[si] Lp1: cmp ax,[si+2] jg next xchg ax,[si+2] next: add si,2 loop lp1 ret findmax endp Code ends
end main
参数的传递
第六章 子程序和宏程序

二、宏程序
在程序中可使用变量、并通过变量赋值、运算及 运用其它能够控制程序执行顺序的控制指令,从而 使程序具有特定功能的程序被称之宏程序。宏程序 的作用与子程序相类似,它具有某种通用功能,由 主程序的专业语句调用,执行完宏程序后再返回主 程序。 宏程序由三部分组成。1、宏程序名:字母O后 接5位自然数;2、宏程序体;3、宏程序结束指令 M99。宏程序名和结束指令与子程序相同,但调用 指令不相同。
G01 Z#8 F#5; ; 以给定的进给速度钻孔 G00 Z#6; ; 从孔底返回 #10=#10+1; ; END 1 GOTO 910; ; N900 #3000=140(DATA LACK); ( ); N910 M99; ;
实例
采用O9100宏程序,加工分布在中心(52,78)的4个均布孔,分 布直径为40mm,起始角度为30°,各孔等分角度为90 °,钻孔时快速 接近平面为5mm,孔深度为20mm,进给速度为100mm/min,刀具快速 返回平面为50mm。其程序如下: O100 G90 G54 ; G00 S540 M3 Z100; G43 H01; G65 P9100 X52.0 Y78.0 I40.0 B90.0 D4.0 A30.0 C5.0 E-20.0 J100. K50.0; G00 X0 Y0; G49 Z0; M30;
子程序1 钻孔) 子程序1(钻孔)
O1000 N0001 G00 G90 Z5.0; 快速接近工件 N0005 G01 Z-35.F100.; 钻孔 N0010 G00 Z5.0; 快速返回参考平面 N0015 M99; 子程序结束
子程序2 子程序2(从左至右钻4个孔)
O1001 N0001 N0005 N0010 N0015 N0020 N0025 N0030 N0035 P1000; M98 P1000; X30.; G91 X30.; P1000; M98 P1000; X30.; G91 X30.; P1000; M98 P1000; X30.; G91 X30.; P1000; M98 P1000; M99; M99; 调用子程序1 调用子程序1,钻1号孔,返回参考平面 号孔, 移动到2 移动到2号孔 调用子程序1 号孔, 调用子程序1,钻2号孔,返回参考平面 移动到3 移动到3号孔 调用子程序1 号孔, 调用子程序1,钻3号孔,返回参考平面 移动到4 移动到4号孔 调用子程序1 号孔, 调用子程序1,钻4号孔,返回参考平面 子程序结束
第5章 子程序

子程序名
ENDP
在子程序入口处把相关寄存器的值入栈保护,程序返回前再 恢复它们的值,这个操作称为“保护现场”和“恢复现场”。
5.1.3
子程序文档
设计一个子程序之前,首先应该明确:
子程序的名字;
子程序的功能; 入口参数:为了运行这个子程序,主程序为它准备了哪几个 “已知条件”?这些参数存放在什么地方? 出口参数:这个子程序的运行结果有哪些?存放在什么地方? 影响寄存器:执行这个子程序会改变哪几个寄存器的值? 其它需要说明的事项。 上述内容连同子程序源代码等合称为“子程序文档”。 常常把上述内容以“程序注释”的方式书写在一个子程序的首部。
RET指令
无参数段内返回 格式:RET
操作:IP← SS: [SP],SP ← SP+2 有参数段内返回 格式:RET D16 ;其中D16代表16位数据 操作:IP ← SS:[SP],SP← SP+2 SP ← SP+D16 无参数段间返回 格式:RET 操作: IP ← SS:[SP], SP ← SP+2 CS ← SS:[SP], SP ← SP+2 有参数段间返回 格式:RET D16 ;其中D16代表16位数据 操作: IP ← SS:[SP], SP← SP+2 CS ← SS:[SP], SP← SP+2 SP ← SP+D16
段间调用
•
段间直接调用
格式:CALL FAR PTR 子程序名 操作: SP← SP-2, SS:[SP]← CS SP← SP-2, SS:[SP]← IP (以上是保存32位返回地址,偏移地址保存在较小地址处) IP ← 子程序入口的偏移地址, CS← 子程序入口的段基址 • 段间间接调用 格式:CALL MEM32 操作:SP← SP-2, SS:[SP] ← CS SP← SP-2, SS:[SP] ← IP IP← [MEM32],CS←[MEM32+2]
子程序

子程序
机床的加工程序可以分为主程序和子程序两种 主程序:是零件加工程序的主体部分,和被加工零件及加工要求一一对应,不同的零件 或不同的加工要求,都有唯一的主程序; 子程序:为了简化编程,可以将一个或多个程序中的重复动作,编写为单独的程序,并 通过程序调用的形式来执行这些程序,这样的程序称为子程序。
子程序的调用 在大多数数控系统中,子程序的程序号和主程序的格式相同,即:也用O后缀数字组成, 但其结束标记必须使用M99(或M17)才能实现程序的自动返回功能。 子程序只能在自动方式时被调用。主程序可以调用子程序,子程序可以调用另一个子程 序,即使用两级嵌套。一个子程序可以被重复调用999次 。
;钻孔#2, #3, #4孔,返回R平面
N003 M99
;子程序结束
主程序:
O0001
;主程序号
N001 G43 Z20.0 H01
;至起始平面,返回R平面
N002 M03 S3000 ;启动主轴
N003 G00 X100.0 Y100.0
;定位到#1孔
N004 M98 P1000 ;调用子程序加工#1, #2, #3, #4孔
;定位到孔#13
N010 M98 P1000 ;调用子程序加工#13, #14 ,#15, #16孔
N011 G90 G00 Z20.0 H00
;撤消刀具长度补偿
N012 X0 Y0
;返回程序原点
N013 M02
;程序结束
N005 G90 G00 X100.0 Y120.0
;定位到孔#5
N006 M98 P1000 ;调用子程序加工#5, #6 ,#7, #8孔
N007 G90 G00 X100.0 Y140.0
微机原理第04章4子程序

mov ah,9
;;宏定义体
lea dx,message
int 21h
endm
…
dispmsg string ;宏调用(宏指令)
…
1 mov ah,9
;宏展开
1 lea dx,string
1 int 21h
第4章:宏与比子程序的比较
宏
较
子程序
仅是源程序级的简化: 宏调用在汇编时进行 程序语句的展开,不 需要返回;不减小目 标程序,执行速度没 有改变
第4章:例4.16 显示以“0” 结尾字符串的嵌套子程序
msg
;数据段 db 'Well, I made it !',0 ;代码段(主程序) mov si,offset msg ;主程序提供显示字符串 call dpstri ;调用子程序
第4章:例4.16 子程序
;子程序dpstri:显示DS:SI指向的字符串(以0结尾)
第4章:4.6 子程序设计
把功能相对独立的程序段单独编写和调 试,作为一个相对独立的模块供程序使 用,就形成子程序
子程序可以实现源程序的模块化,可简 化源程序结构,可以提高编程效率
主程序(调用程序)需要利用CALL指令 调用子程序(被调用程序)
子程序需要利用RET指令返回主程序
第4章:4.6.1 过程定义和 子程序编写
dpstri proc
push ax
dps1: mov dl,[si] ;取显示字符
inc si
cmp dl,0
;是结尾,则显示结束
jz dps2
call dpchar ;调用字符显示子程序
jmp dps1
dps2: pop ax ret
dpstri endp
子程序

注意:①子程序只能执行有限级嵌套,最多可嵌套4层子程序
②应避免子程序间的互相调用。
例: 零件结构相同应用子程序
O5555; W-20 ; G01 X74 F0.07; G04 X3; G01 X82 ; M93 M08; G00 X82 Z0; M98 P45555; G00 X100; Z100; M30;
子程序
在程序中,当某一部分程序反复出现时, 可以把这类程序作为一个独立程序,并事先存 储起来,使程序简化。这个独立程序称为子程 序。
子程序调用指令M98
子程序结束指令M99
子程序嵌套
1、子程序调用指令M98
格式:
M98 P □□□□××××;
□□□□ ——表示重复调用子程序的 次数,若省略则调用次数为1 次。 ×××× ——表示要调用的子程序号。 P——最多跟8位数字,数字可以小于 或等于4位。
连续调用4次子程 格式:M98 举例:M98
序O12的指令? P □□□□××××;
P46666;
M98 P40012;
M98 P8888;
注意:主程序可以多次调用子程序,但连续调
用同一子程序执行加工,最多可执行999次。
2、子程序结束,并返回主程序指 令M99
格式:M99;
3、子程序嵌套
定义:为进一步简化零件加工程序,子程序亦可再调用另一 子程序,这种调用称为子程序嵌套。
练习:
精加工该轮廓
O9001 G01 W-5 F0.1; G03 W-15 R20; M99;
O9000 G99; T0101; M03 S800; G00 X28 Z2; G01 Z0 F0.2; M98 P49001; G01 W-5; X35; G00 X100; Z100; M05; M30;
子程序

子程序一、子程序的概念把程序中某些固定顺序和重复出现的程序单独抽出来,按一定格式编成一个程序供调用,这个程序就是常说的子程序,这样可以简化主程序的编制。
一次装夹加工多个相同零件,或者一个零件有重复加工部分的情况下可使用子程序。
每次调用子程序时的坐标系、坐标位置、切削用量等可根据情况改变,甚至可以对子程序进行镜像、缩放、旋转等。
子程序可以被主程序调用,同时子程序也可以调用另一个子程序。
二、子程序的格式OxxxxN1000 —N1010 ———N1020 ———N1030 _N1040 M99在子程序的开头,继“O”(EIA)或“:”(ISO)之后规定子程序号,子程序号由4位数字组成,前边的“0”可省略。
M99为子程序结束指令。
M99不一定要独立占用一个程序段,如G00 X Y_Z_M99也是可以的。
三、子程序的调用调用子程序的格式为:M98 Pxxxx Lxxxx其中M98是调用子程序指令,地址P后面的4位数字为子程序号,地址L为重复调用次数,若调用次数为“1”可省略不写,系统允许调用次数为9999次。
主程序调用某一子程序需要在M98后面写上子程序号,此时要改子程序Oxxxx为Pxxxx。
四、子程序的执行过程以下列程序为例说明子程序的执行过程:主程序O0001;N0010N0020 M98 P1010 L2;N1030N0040 M98 P1010;N0050 子程序O1010;N1020N1030N1040N1050N1060 M99;主程序执行到N0020时就调用执行O1010子程序,重复执行两次后,返回主程序,继续执行N0020后面的程序段,在N0040时再次调用O1010子程序一次,返回时又继续执行N0050及其后面程序。
当一个子程序调用另一个子程序时,其执行过程同上。
五、子程序的特殊调用方法1.子程序中用P指令返回的地址除子程序结束时用M99指令返回主程序外,还可以在M99程序段中加入Pxxxx,则子程序在返回时,将返回到主程序中顺序号为Pxxxx程序段,如上例中把子程序中N1060程序段中的M99改成M99P0010,则子程序结束时,便会自动返回到主程序N0010程序段,但这种情况只用于储存器工作方式而不能用于纸带方式。
子程序

子程序
1.子程序的概念
(1)子程序的定义 机床的加工程序可以分为主程序和子程序两种。 主程序:一个完整的零件加工程序,或是零件加工 程序的主体部分。 子程序:在编制加工程序中,有时会遇到一组程序 段在一个程序中多次出现,或者在几个程序中都要 使用它,这个典型的加工程序可以做成固定程序, 并单独加以命名。 注意: 子程序一般都不可以作为独立的加工程序使用,它 只能通过主程序进行调用,实现加工中的局部动作。 子程序执行结束后,能自动返回到调用它的主程序 中。
• 例3-18 试用子程序方式编写图3-44所示零件的加工程序
• 工件坐标系原点设在球面SR15右顶点处,加工程序如下:
• • • • • • • • • • •
O0050; G54; T0101; 图3-44 子程序调用示例 M03 S5800; G00 X41.0 Z2.0; G71 U1.5 R0.3; 粗车外圆表面 G71 P100 Q200 U0.3 W0.2 F150; N100 G00 X0.0; G01 Z0 F60; G03 X30.0 Z-15.0 R15.0; G01 Z-66.0;
调用子程序0001 ,6次3.子程序的调用• 格式一:M98 P_ _ _ _ L_ _ _ _ • 例:M98 P200 L5 • 其中,地址符P后面的4位数字为子程序号,地址L 的数字表示重复调用的次数,子程序号及调用次 数前的0可省略不写。如果只调用子程序一次,则 地址L及其后的数字可省略。 • 格式二:M98 P_ _ _ _ _ _ _ _ • 例:M98 P51001 • 地址P后面的8位数字中,前4位表示调用次数,后 4位表示子程序号。采用这种调用格式时,调用次 数前的0可以省略不写,但子程序号前的0不可省 略。如上例中表示调用O1001子程序5次。
第7章子程序设计

程序如下: ; 7-5.asm 堆栈传参。实现两个矩阵的乘法c=a*b data segment a db 1,1,1,1 db 2,2,2,2 db 3,3,3,3 b db 1,1,1 db 2,2,2 db 3,3,3 db 4,4,4 m dw 3 ;A矩阵3行4列 n dw 4 ;B矩阵4行3列 p dw 0 c db 9 dup(?) ;C矩阵3行3列 data ends code segment assume cs:code,ds:data main proc far
;子程序2:查表,显示十六进制 let2: mov dx,offset mess2 ;显示提示2 mov ah,9 int 21h mov bx,x mov ch,4 mov cl,4 rept1: rol bx,cl ;0031→0310→3100→1003→0031 mov al,bl and ax,000fh ;保留最低4位 mov si,ax mov dl,hex[si] ;查表显示高位、低位 mov ah,2 out1: int 21h mov ah,4ch dec ch int 21h jnz rept1 code ends ret end start
7.2 调用和返回
CALL指令和RET指令是机器指令。调 用指令CALL与无条件转移指令JMP一 样,都是对指令指针寄存器IP作修改 后,转移到子程序执行。 有时也需要修改代码段寄存器CS的值, 作跨段调用。因此都有转移地址的寻 址方式问题。
7.2.1 调用指令CALL
格式: CALL 子程序名 功能:转移到指令指定的地址(子程序 名)去执行子程序。CALL指令必须指定 转移的目标地址。执行时,先将断点入 栈保存,再修改IP或修改IP、CS。
;子程序3,将bx中的数显示为十进制数 subr3 proc near mov ax,bx ;bx为传参寄存器 mov cx,0 mov bx,10 let1: ;将ax变为十进制数 mov dx,0 inc cx ;统计余数个数 idiv bx ;除以10,商在AX,余数在DX push dx ;保存余数 cmp ax,0 jnz let1 let2: ;循环显示余数 pop ax add ax,0030h mov dl,al mov ah,2 int 21h loop let2 ret subr3 endp ;将余数弹入ax ;调整为ASCII码
子程序简介

子程序简介1.子程序的概念在一个加工程序中,如果其中有些加工内容完全相同或相似,为了简化程序,可以把这些重复的程序段单独列出,并按一定的格式编写成子程序。
主程序在执行过程中如果需要某一子程序,通过调用指令来调用该子程序,子程序执行完后又返回到主程序,继续执行后面的程序段。
(1)子程序的嵌套为了进一步简化程序,可以让子程序调用另一个子程序,这种程序的结构称为子程序嵌套。
在编程中使用较多的是二重嵌套,其程序的执行情况如下图所示。
图子程序的嵌套(2)子程序的应用1)零件上若干处具有相同的轮廓形状,在这种情况下,只要编写一个加工该轮廓形状的子程序,然后用主程序多次调用该子程序的方法完成对工件的加工。
2)加工中反复出现具有相同轨迹的走刀路线,如果相同轨迹的走刀路线出现在某个加工区域或在这个区域的各个层面上,采用子程序编写加工程序比较方便,在程序中常用增量值确定切入深度。
3)在加工较复杂的零件时,往往包含许多独立的工序,有时工序之间需要适当的调整,为了优化加工程序,把每一个独立的工序编成一个子程序,这样形成了模块式的程序结构,便于对加工顺序的调整,主程序中只有换刀和调用子程序等指令。
2.调用子程序M98指令指令格式:M98P__××××指令功能:调用子程序指令说明:P__为要调用的子程序号。
××××为重复调用子程序的次数,若只调用一次子程序可省略不写,系统允许重复调用次数为1~9999次。
3.子程序结束M99指令指令格式:M99指令功能:子程序运行结束,返回主程序指令说明:(1)执行到子程序结束M99指令后,返回至主程序,继续执行M98P_××××程序段下面的主程序;(2)若子程序结束指令用M99P_格式时,表示执行完子程序后,返回到主程序中由P_指定的程序段;(3)若在主程序中插入M99程序段,则执行完该指令后返回到主程序的起点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第七章子程序和程序包目标本节课的主要目标就是了解子程序和程序包。
为什么会用到子程序?引入什么是子程序?子程序就是能够接受参数并被其他程序所调用的命名PL/SQL块。
PL/SQL子程序有两种类型,过程和函数。
一般地,过程用于执行一个操作,而函数用于计算一个结果值。
与未命名或匿名PL/SQL块一样,子程序也有声明部分,执行部分和一个可选的异常处理部分。
声明部分包含类型、游标、常量、变量、异常和嵌套子程序的声明。
子程序子程序分为过程(store procedure)和函数(function),是一种特殊的pl/sql语句块。
它以编译好的的形式存储在数据库中,可以被后来的语句块调用。
运行时是编译而不是运行,要调用才会有结果。
DML增、删、改用过程,计算用函数。
过程:没有返回值。
函数:有且只有一个返回值。
子程序作用:1、允许模块化编程2、能够实现较快的执行过程3、能够减少网络流量4、可作为一种安全机制存储过程创建过程的语法CREATE[OR REPLACE]PROCEDURE<procedure name>[(<parameter list>)]IS|AS<local variable declaration>BEGIN<executable statements>[EXCEPTION<exception handlers>]END;存储过程中定义的形式参数,不能指定长度,否则报错。
1.不带参数的存储过程create or replace procedure test1isbegindbms_output.put_line('大家好');end;执行:SQL>set serveroutput onSQL>exec test1;任何的输出都要先执行SQL>set serveroutput on否则就无法看到输出结果,为什么呢?任何的输出在客户端看不见,他直接往oracle服务器上去输出。
执行这句让它在控制台上也输出一份。
2.带输入参数create or replace procedure test2(a in number,b in varchar2)isbegindbms_output.put_line(a);dbms_output.put_line(b);end;调用SQL>exec test2(1,'a');1a3.带有输出参数create or replace procedure add_proc (x in number,y in number,z out number)asbeginz:=x+y;end;调用:SQL>var result number;SQL>exec add_proc(1,3,:result);PL/SQL procedure successfully completed Print result---------4SQL>print result;result---------44带有in out的参数create or replace procedure test4(a in out number,b in out number)astemp number;begindbms_output.put_line(a);dbms_output.put_line(b);temp:=a;a:=b;b:=temp;end;调用:SQL>var n1numberSQL>var n2numberSQL>exec:n1:=1SQL>exec:n2:=3PL/SQL过程已成功完成。
SQL>exec test4(:n1,:n2);13PL/SQL过程已成功完成。
SQL>print n1n2;N1----------100N2----------200SQL>组合应用--设计一个存储过程,接受一个员工的姓名,返回一个员工的工资--另外,如果员工的工资>3000,输出一个‘高薪’的字符串--否则,输出低薪create or replace procedure getnamebysal(v_name emp.ename%type,v_sal out emp.sal%type,v_level out varchar2)is--这里可以定义变量v_temp emp.sal%type;beginselect sal into v_temp from emp where ename=v_name;v_sal:=v_temp;if v_temp>3000thenv_level:='高薪';elsev_level:='低薪';end if;end;--使用pl/saldeclareV_NAME varchar2(20):='SMITH';v_sal emp.sal%type;v_level varchar2(20);begingetnamebysal(v_name,v_sal,v_level);dbms_output.put_line(v_sal);dbms_output.put_line(v_level);end;存储过程之间可以相互调用:CREATE OR REPLACE procedure test8asvalue1varchar(10):='KING';value2number;begintest7(value1,value2);dbms_output.put_line(value2);end;参数的传递位置传递名称传递exec test4(var1=>’a’,var2=>’b’);组合传递查看过程源码select text from user_source where name='TEST4';维护子程序查看编译错误:show errors删除子程序:Drop procedure procedure_name;Drop function function_name;注意:在存储过程中不能够使用select语句直接查询,否则会出现编译错误。
函数和存储过程相似,但是要明确规定返回值。
不带参数--函数create or replace function get_userreturn varchar2--返回值类型,不加长度isv_name emp.ename%type;beginselect ename into v_name from emp where empno='7369';return v_name;end;执行:调用SQL>var v1varchar2(100);SQL>exec:v1:=get_userPL/SQL过程已成功完成。
SQL>print v1V1--------------------------------SCOTT或者select get_user from dual;带参数查找指定员工的工资create or replace function get_sal(e_name in varchar2)return numberasv_sal emp.sal%type;beginselect sal into v_sal from emp where upper(ename)=upper(e_name);return v_sal;exceptionwhen NO_DATA_FOUND THENraise_application_error(-20000,'员工不存在');end;带有out参数如果要返回多个值,可以使用out参数create or replace function get_info(e_name varchar2,title out varchar2)return varchar2asdeptname dept.dname%type;beginselect a.job,b.dname into title,deptnamefrom emp a,dept bwhere a.deptno=b.deptnoand upper(a.ename)=upper(e_name);return deptname;end;调用SQL>var job varchar2(20);SQL>var dname varchar2(20);SQL>exec:dname:=get_info('scott',:job)PL/SQL过程已成功完成。
SQL>print dname jobDNAME--------------------------------RESEARCHJOB--------------------------------ANALYSTSQL>带有in out参数create or replace function testf(num1number,num2in out number)return numberasv_result number(6);beginv_result:=num1/num2;num2:=mod(num1,num2);return v_result;end;调用SQL>var result1numberSQL>var result2numberSQL>exec:result2:=30PL/SQL过程已成功完成。
SQL>exec:result1:=testf(100,:result2) PL/SQL过程已成功完成。
SQL>print result1result2; RESULT1----------3RESULT2----------10。