What are the effects of PR instruction on empty stack

130 Views Asked by At

When I issue the PR (Program Return) instruction in a program that is not using linkage stacks, the program immediately ends. I'd like to take advantage of this behavior, but I'd like to know if I will cause any unintended results besides exiting my program? I've read the PR description in the principal of operations manual, but didn't see anything that answered my question.

If the PR instruction is not appropriate for immediate program termination, is there another method I should be using?

2

There are 2 best solutions below

0
On BEST ANSWER

First, there's no such thing as "a program that is not using linkage stacks", otherwise your PR instruction would cause an exception (abend).

Also, from the IBM Principles of Operation:

If the backward stack-entry validity bit, bit 63, of the current entry is zero, a stack-empty exception is recognized, and the operation is nullified;

This suggests that not only is there a linkage stack, but there is at least one frame on it, otherwise your PR instruction would fail with the stack-empty condition.

The "standard" way of terminating a program without using standard linkage and returning to that R14 address you were passed would be to issue an SVC 3 instruction (SVC 3 is "EXIT"...terminate the current RB). Indeed, if you look closely, you'll see that the R14 return address that you're passed at entry to a job step program is simply pointing to CVTEXIT, an SVC 3 instruction, so this is exactly what you're doing when you do BR 14 (or whatever) at the end of your program - no reason you can't issue the SVC 3 yourself.

Piecing this together, it sounds like when z/OS attaches your program, it passes you a linkage stack with a frame having a PSW pointing to an SVC 3 instruction. When you issue PR before anything else changes the stack, you're indirectly taking a long branch to this SVC 3 instruction and your program ends.

You can validate this yourself - take a dump at entry to your program, and look at the formatted linkage stack. If you don't know how to do this, just create a one line assembler program with DC F'0' at the entry point and run it in batch with a //SYSMDUMP DD statement allocated (SYSMDUMP = machine readable dump). Then you can use IPCS to view the dump interactively and figure all this stuff out (and that's a valuable skill to have in its own right!).

0
On

Normally one has entry logic to save the callers registers. Exceptions include code intended to set up register values for the caller.

If you want to return to your caller, BR to the return register in the BASR. Simply exiting the entire process isn't a good idea because you don't know how you were invoked. Maybe program A invoked you. Maybe A invoked B which invoked C which invoked you, and A, B, and C all need to do cleanup work before exiting. I was taught to always return to your caller.

While today you know how you were invoked, you don't know whether the useful task being performed by the code in question will be reused by other programs in the future, perhaps in ways as yet undreamt of.