IBM S/360 Subroutines

Mark Smotherman. Last updated February 2012.


The IBM S/360 was introduced in 1964 as a consolidation of several different IBM computer families. The S/360 architecture is based on 32-bit words that are byte-addressed in memory using 24-bit addresses. There are 16 general registers, each of 32 bits in width. This mainframe architecture lives on today in the IBM zSeries architecture (having been through multiple instruction set extensions along the way: S/370, S/370-XA, ESA/370, and ESA/390).

Subroutine instructions

        balr rA,rB  - branch and link register - rA <- updated PC;
                                                 if(B!=0) PC <- rB

        br   rA     - branch register          - if(A!=0) PC <- rA

Register conventions

        r0  - holds return code set by subroutine
        r1  - holds single parameter or address of parameter list
        r13 - holds address of 18-word save area
        r14 - holds return address
        r15 - holds beginning address of subroutine
S/360 programmers typically follow a callee save convention using a save area in memory.

Calling program structure

           l    r15=A(subr)            ! load address of subroutine in r15
           balr r14,r15                ! save return address in r14 and set
           ...                         !    pc to contents of r15

Subroutine structure

           stm  r14,r12,12(r13)        ! store multiple registers into caller's
                                       !    save area (r14,r15,r0,...,r12)
           balr r12,0                  ! set address in r12 for use as base reg
           using *,r12                 ! pseudo-op to tell assembler to use r12
           la   r11,savearea           ! load address of my save area
           st   r13,savearea+4         ! store address of caller's save area
           st   r11,8(r13)             ! store address of my save area in
                                       !    caller's save area

           ... body of subroutine ...

           ... r0 is used for return code, if present ...

           l    r13,savearea+4         ! load address of caller's save area
           lm   r14,r12,12(r13)        ! load multiple registers from caller's
                                       !    save area (r14,r15,r0,...,r12)
           br   r14                    ! return to caller

           ds   18f    ! 18-word save area
                       !    byte  0: reserved
                       !    byte  4: address of caller's save area
                       !    byte  8: address of called subroutine's save area
                       !    byte 12: contents of r14
                       !    byte 16: contents of r15
                       !    byte 20: contents of r0
                       !    byte 24: contents of r1
                       !    ...
                       !    byte 68: contents of r12

Further discussion


Thanks to Alan Larson for providing corrections to the original code.

[History of subroutines page] [Mark's homepage] [CPSC homepage] [Clemson Univ. homepage]