Mainframe Path Start learning free
Applied11 min readLesson 2 of 3

Common instructions and linkage conventions

A small set of instructions does most of the work in real assembler code: load, store, move, compare, packed decimal arithmetic and branch. Programs call each other using fixed register conventions, so any program, in any language, can call any other. Learn both and most modules become readable.

The everyday instructions

InstructionFormatWhat it does
L R,addrRXLoad 4 bytes (a fullword) from storage into a register
ST R,addrRXStore the register's 4 bytes into storage
LA R,addrRXLoad the address itself into the register; storage is not read
MVC to(len),fromSSMove 1 to 256 bytes from one storage area to another
CLC a(len),bSSCompare two storage areas byte by byte; set the condition code
AP a,bSSAdd packed decimal field b to field a
CVB R,dwordRXConvert an 8-byte packed field to binary in a register
CVD R,dwordRXConvert a register's binary value to an 8-byte packed field
BAL / BALRRX / RRSave the return address in a register, then branch
BC mask,addr / BR RRX / RRBranch if the condition code matches the mask; BR is unconditional

Two traps catch beginners. LA does not touch storage: LA 3,10(0,0) puts the number 10 in R3, and it is often used that way to load small constants or to step a pointer. And MVC moves exactly the length it is given, with no padding and no awareness of field types, so a wrong length silently overwrites the next field.

AP works on packed decimal fields, the same format as COBOL COMP-3. If either field does not contain valid packed data, the instruction fails with a data exception, which is the S0C7 abend. CVB fails the same way on invalid packed input.

The condition code and branch masks

Many instructions set a 2-bit condition code (CC) in the PSW. BC then tests it with a 4-bit mask: each bit stands for one CC value. If any selected bit matches the current CC, the branch is taken.

Mask bitTestsAfter CLCAfter AP
8CC 0EqualResult zero
4CC 1First operand lowResult negative
2CC 2First operand highResult positive
1CC 3(not set)Overflow

Masks add together: BC 15 branches always (the extended mnemonic B), BC 0 never branches, and BC 7 (8 not set) means not equal. The assembler provides readable extended mnemonics such as BE (BC 8), BNE (BC 7), BL (BC 4) and BH (BC 2). BR 14 is BCR 15,14: branch always to the address in R14.

TRY IT YOURSELF

What BC mask value branches only when the condition code is 0 (for example, after CLC finds the fields equal)?

Show a hint

Mask bits 8, 4, 2, 1 correspond to CC 0, 1, 2, 3.

Show the solution

8. The leftmost mask bit (value 8) tests CC 0, so BC 8 is the same as BE.

Standard linkage conventions

When one program calls another, both sides follow the same register conventions. This is why a COBOL program can call an assembler routine, and why an exit written by a site can be driven by z/OS.

RegisterOn entry to the called programOn return to the caller
R1Address of the parameter listVaries by interface
R13Address of the caller's 72-byte save areaRestored to the caller's save area
R14Return address in the callerRestored; used to branch back
R15Entry point address of the called programReturn code (0, 4, 8, 12...)

The called program first saves the caller's registers into the caller's save area, then provides its own save area for anything it calls, chaining the two together. At the end it restores the registers, puts the return code in R15 and branches back through R14.

Save area chaining between caller and called program
CallerR13 points to its save area
STM 14,12,12(13)callee saves caller's registers
Chainback pointer at +4, forward pointer at +8
LR 13,newcallee's own save area
Returnrestore, R15 = RC, BR 14
Typical entry and exit logic (illustrative)
DATECHK  CSECT
         STM   14,12,12(13)     save caller's registers
         LR    12,15            entry address becomes base
         USING DATECHK,12
         LA    11,SAVEAREA      our own save area
         ST    13,4(,11)        back chain to caller's area
         ST    11,8(,13)        forward chain from caller's area
         LR    13,11
         L     2,0(,1)          address of first parameter
*        ... processing ...
         L     13,4(,13)        back to caller's save area
         L     14,12(,13)       restore return address
         LM    0,12,20(13)      restore R0 to R12
         SR    15,15            return code 0
         BR    14
SAVEAREA DS    18F

The parameter list is a list of fullword addresses, one per parameter. In 31-bit code the high-order bit of the last address is set to mark the end of a variable-length list. COBOL CALL ... USING builds exactly this list, and the COBOL RETURN-CODE special register picks up R15 after the call. Many sites use the SAVE and RETURN macros to generate this code. 64-bit programs use a larger save area format, but the idea is the same.

Common mistakes

Using LA when you meant L

LA loads an address, L loads the data at that address. Swapping them gives wrong values without any abend, so check every one when reviewing.

Getting the MVC length wrong

MVC moves exactly the length coded or implied by the first operand. A longer move overwrites neighbouring fields silently; use explicit lengths and check field definitions.

Overwriting R15 before returning

Restoring all registers with LM 14,12 after setting the return code wipes the RC. Set R15 after the restore, or skip it in the restore, as in the example.

What you will see at work

Key terms

Check your understanding.
Take this lesson's quiz and save your progress. Free.

Take the lesson quiz
← Why assembler still matters: registers and addressingStorage definitions, dumps and program checks →