The Punctilious Programmer IBM Mainframe Assembler Standard Entry and Exit Video

Standard Entry and Exit Video

How do we get in and out of a program? I call it my standard entry and exit code, but in fact, there are multiple ways of getting the job done while following IBM’s linkage conventions. Here’s a video explanation of the way I do it, line-by-line, with visuals. It’s also #24 on the IBM Mainframe Assembler page.

6 thoughts on “Standard Entry and Exit Video”

  1. Another *excellent* video, with a generous treatment of the topic and nice visuals.
    I notice you use BASR 12,0 (was “BALR” way back when) to set the Base Register (R12). This is also how I was taught, but after quite some time contemplating how to improve on it, come to trust using “LR R12, R15” to accomplish the same thing. This also solves BASR/BALR’s annoying characteristic of leaving the location counter out of sync with the offset from the Entry Point:

    . . . .Object
    Loc.Code . . . . . . . . . . . Source Statement
    . . . . . . . . . . . . . . . . . . . .CSECT. . .CSECT
    000000 0DC0 . . . . . . . . . . . . . . . BASR 12,0
    . . . . . . . . . . . . . . . . . . . . . . . . . . . .USING *,12
    => Note how Assembler shows EXIT location at “…C004” (R12 + 4):
    000002 47F0 C004 . . . . . . . . . . . B EXIT
    => But LOCTR puts “EXIT” at Entry Point + 6: 🙁
    000006 07FE . . . . . .. . . EXIT. . . . .BR 14

    With “LR R12, R15” the issue goes away:
    . . . . . . . Object
    Loc. . . . Code. . . . . . . . . . .Source Statement
    . . . . . . . . . . . . . . . . . . . . . . .CSECT CSECT
    000000 18CF . . . . . . . . . . . . . . . . . LR R12,R15
    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .CSECT,R12
    => Now Assembler shows EXIT location at “…C006” (R12 + 6):
    000002 47F0 C006 . . . . . . . . . . . . .B EXIT
    => Matching LOCTR value for “EXIT” (Entry Point + 6)
    000006 07FE . . . . . . . . . . . EXIT BR 14

    1. Hi David, I do like the LR R12,R15 technique, and it’s probably an improvement over what I coded. Having the base address at the top of the CSECT makes debugging easier. I think I stuck with the old technique so that students would get used to base addresses that weren’t at the top. (Not nice of me.) For anyone just learning this stuff, David’s technique establishes addressability immediately. After what he’s coded, you would follow up by saving the registers and getting register 13 to point at your own SAVE area. Give it a try.

      I think BASR was designed to replace BALR for 31 and 64 bit addressing, so I’ve switched. Thanks for weighing in.

  2. Continuing the idea of using “LR R12,R15” vs “BASR R12,R15” to set a Base Register on entry, the question naturally arises “How can you be sure R15 actually *does* contain the Entry Point address on entry?”
    Indeed, there *are* some very specific cases where it will *not*. With AMODE 64, for instance, where the low-order bits in R15 can have a value of 0, 1, 2, or 4 depending on various factors. But, since all well coded AMODE 64 programs use branch *relative* anyway, rather than *offset from a base*, this obviates the *need* for any Base Register.
    Apart from such specific and limited cases, the precedent that IBM has established as the default, going all the way back to System/360, is that “R15 shall contain the Entry Point address on entry”. This can be seen in IBM’s own macros.
    In the except below, note how SAVE (14,12),,* expands (“*” indicating the current CSECT name should be embedded) to generate a *hard-coded* branch around the CSECT name, using R15 as the base => “B 10(0,15)”
    0000 . . . . . . . . . . . 1 CSECT CSECT
    . . . . . . . . . . . . . . . 2 . . . . SAVE (14,12),,*
    0000 47F0 F00A . . 4+ . . . B 10(0,15)
    0004 05 . . . . . . . . . 5+ . . . DC AL1(5)
    0005 C3E2C5C3E3 6+ . . . DC CL5’CSECT’
    000A 90EC D00C 7+ . . . STM 14,12,12(13)

    ==> See the “SAVE” macro doc here:
    http://www.ibm.com/docs/en/zos/2.5.0?topic=xct-save-save-register-contents – “Write the SAVE macro only at the *entry point* of a program … the macro expansion *requires that register 15 contain the address of the SAVE macro* …

    SAVE doesn’t check first to make sure R15 is set. Nor does it provide any means to use any register *other than* R15. It simply assumes R15 *is* the actual entry point. And that’s how it’s been decades. No APAR has ever been issued against the SAVE macro which would change this assumption.

    Likewise with CALL and LINK. Each is designed to ensure R15 contains the Entry Point address on entry:

    CALL:
    http://www.ibm.com/docs/en/zos/2.5.0?topic=section-call-description
    “On entry to the called program, the register contents are as follows:
    […]
    R15 – Entry address of the called program”

    LINK:
    http://www.ibm.com/docs/en/zos/2.5.0?topic=module-link-linkx-description – “If the LINK is successful, the GPRs contain the following when the called program receives control:
    […]
    R15 Requested program’s entry point address”

    Given the abundance of evidence that R15 can be relied on to contain the Entry Point Address on entry, here’s the standard entry code I’ve been using for decades and never had a problem with it:
    . . . SAVE (14,12),,*
    . . . LR 12,15
    . . . USING ,12

  3. Your standard entry with BASR R12,0 does result in the object text displacement being different to the location counter offset but there is an easy way to see where an operand is – the listing has two columns labelled ADDR1 and ADDR2 – these will give you the offset of operand1 and 2 respectively.
    These columns can be useful when dealing with relative addresses.

Leave a Reply to dwoolbrightCancel reply