子程序通常使用 CALL(实际上是ACALL或LCALL)和 RET指令来进行调用和返回。具体使用哪个指令取决于子程序是近调用(near call)还是远调用(far call)。
CALL指令
近调用(near call):使用CALL指令,不需要改变堆栈指针,直接将子程序地址压入堆栈。
远调用(far call):使用CALL指令,需要将子程序地址压入堆栈,并且可能还需要改变堆栈指针(取决于具体的调用约定)。
RET指令
返回:子程序执行完毕后,使用RET指令从堆栈中弹出先前压入的子程序地址,并跳转到该地址继续执行。
示例
```assembly
; 主程序
START:
MOV R3, 7
CALL ALL_THE_ZEROS ; 调用子程序
MOV R7, 4
CALL ALL_THE_ZEROS ; 调用子程序
; ... 其他指令
; 子程序 ALL_THE_ZEROS
ALL_THE_ZEROS:
MOV R0, 0
MOV R1, 1
MOV R2, 2
MOV R3, 3
MOV R4, 4
MOV R5, 5
MOV R6, 6
MOV R7, 7
RET ; 从子程序返回
```
注意事项
子程序可以嵌套调用,但嵌套层数通常有限制(例如,FANUC系统最多允许4级嵌套)。
调用子程序时,需要确保子程序号(P)和重复调用次数(L)正确无误。
不同的数控系统可能有不同的子程序结束指令(例如,FANUC系统使用M99,西门子系统使用M17)。