当我在不使用链接堆栈的程序中发出PR(程序返回)指令时,程序立即结束。 我想利用这种行为,但我想知道除了退出程序之外,我是否会导致任何意外结果? 我已经阅读了操作手册原理中的 PR 描述,但没有看到任何回答我的问题的内容。
如果 PR 指令不适合立即终止程序,我应该使用其他方法吗?
首先,没有"不使用链接堆栈的程序"这样的东西,否则您的 PR 指令会导致异常(异常结束)。
此外,根据 IBM 操作原理:
如果当前条目的向后堆栈条目有效性位(位 63) 为零,识别堆栈空异常,操作 无效;
这表明不仅有一个链接堆栈,而且上面至少有一个帧,否则您的 PR 指令将失败并出现堆栈空状态。
不使用标准链接终止程序并返回到您传递的 R14 地址的"标准"方法是发出 SVC 3 指令(SVC 3 是"EXIT"...终止当前 RB)。事实上,如果你仔细观察,你会发现你在进入作业步骤程序时传递的 R14 返回地址只是指向 CVTEXIT,一个 SVC 3 指令,所以这正是你在程序结束时执行 BR 14(或其他什么)时所做的 - 没有理由你不能自己发出 SVC 3。
将这一点拼凑在一起,听起来就像当 z/OS 附加你的程序时,它会向你传递一个链接堆栈,该堆栈带有一个带有指向 SVC 3 指令的 PSW 的帧。当您在其他任何更改堆栈之前发出 PR 时,您将间接地将长分支带到此 SVC 3 指令,并且您的程序结束。
您可以自己验证这一点 - 在程序入口处进行转储,并查看格式化的链接堆栈。如果您不知道如何执行此操作,只需创建一个在入口点使用 DC F'0' 的单行汇编程序,并在分配//SYSMDUMP DD 语句的情况下批量运行它(SYSMDUMP = 机器可读转储)。然后,您可以使用IPCS以交互方式查看转储并弄清楚所有这些内容(这本身就是一项宝贵的技能!
通常有入口逻辑来保存调用方寄存器。 例外情况包括旨在为调用方设置寄存器值的代码。
如果要返回呼叫者,请BR
BASR
中的返回寄存器。 简单地退出整个过程不是一个好主意,因为您不知道您是如何被调用的。 也许程序A调用了你。 也许 A 调用了调用 C 的 B 调用了你,而 A、B 和 C 都需要在退出之前进行清理工作。 我被教导要总是回到你的来电者那里。
虽然今天你知道你是如何被调用的,但你不知道所讨论的代码正在执行的有用任务是否会在未来被其他程序重用,也许是以前所未有的方式。