2 RET指令会将子程序的返回地址d出堆栈,并跳转到该地址执行主程序。
3 在主程序中,可以继续执行下一条指令,完成整个程序的执行。
在 C 语言中,可以使用函数的返回值来实现从子程序中直接跳转到其他地方。例如,您可以在 R_NEED_MAN_DO 子函数中添加一个 if 语句,判断 PLC_GI0 的值是否为 88,如果是,则返回一个特定的值,用于指示在主函数中跳转到其他位置。您可以使用 return 语句来实现这一点。示例代码如下:
int R_NEED_MAN_DO() {
// do something...
if (PLC_GI0 == 88) {
return 1
}
// do something else...
}
然后,在您的主函数中,可以根据 R_NEED_MAN_DO 的返回值来实现跳转。例如,如果返回值为 1,则可以使用 goto 语句跳转到指定的位置。示例代码如下:
int main() {
// do something...
int result = R_NEED_MAN_DO()
if (result == 1) {
goto my_label
}
// do something else...
my_label:
// do something after jump...
}
请注意,在大多数情况下,使用 goto 语句来实现跳转是不推荐的,因为它会导致代码难以维护和理解。在实际编写代码时,应尽量避免使用 goto 语句,并尝试使用其他结构来控制程序流程。
这个当然是能使用LJMP指令重主程序跳转到子程序,或从子程序跳回主程序,但一般是不允许这样使用LJMP指令的,很容易造成程序运行混乱。因为调用子程序保护现场要将当前的地址压入堆栈,子程序返回时,会d出该地址赋值给PC指针。如果使用,必须满足以下条件:跳出跳入成对出现,也就是说,从主程序用LJMP跳转到子程序,那么在子程序中的RET前,必须是用LJMP指令跳回。不成对出现,但是如果子程序是LJMP跳转来的控制,那么在RET前,需要压入返回位置的地址。由于单片机的RAM是有限的,程序在进入子程序之前经常会使用RAM来临时存储一些数据,包括SP指针在执行完子程序之后需要跳回的地址信息。也就是堆栈的“压栈”(PUSH)。
子程序执行完后,要执行一个RET指令结束子程序,指针指向的堆栈单元读取堆栈数据,这个过程叫做“出栈”(pop),然后指针会正常的运行下去。假如在子程序内直接用LJMP指令跳出到主程序,就会把堆栈压入的数据没有读出,造成数据丢失,SP指针指向的地址没有正确返回,造成堆栈不断增加,直到不够用了就会溢出。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)