The LOOPS and SUBROUTINES are two of the most important
constructs which are at the heart of all programming paradigms.
The IBM's BAL (360) provides support for creating efficient
LOOPS and SUBROUTINE calls with help of a rich inventory of the
instructions at hand.
CREATING LOOP STRUCTURES
The LOOPS are essentially the chunks of code which are executed
repeatedly subject to certain control condition. Two types of
looping structures are most frequently encountered:
- Type1: Loop with known number of cycles
- Type2: Loop with unknown number of cycles
The Type 1 loops are often created either of following instructions:
The effect of executing either of these is shown in following pseudocode:
BCT:
|r1| = |r1|-1
if(|r1|!=0) take branch to D(X,B)
else go to next instruction
1. Condition code remains unaltered.
BCTR:
|r1| = |r1|-1
if((|r1|!=0)&&(|r2|!=R0)) take branch to |r2|
else go to next instruction.
1. Condition code remains unaltered.
|
The type 2 loops are created using either of following:
BXLE r1,r2,D(B)
BXH r1,r2,D(B)
1. Note the absence of X in address.
|
Both of these are examples of type RS instructions that
are coded as follows.
h_{0}h_{0}h_{r1}h_{r2}h_{b}h_{D}h_{D}h_{D}
Where:
h_{0}h_{0} : Machine code of the instruction
h_{r1}: Register r1
h_{r2}: Register r2
h_{B} : Base Register
h_{D} : 3 Byte displacement
|
Whenever either of these are present, following are assigned:
- Index Register (INDR)
- Increment Register (INCR)
- Limit Register (LIMR)
This is done according to following pseudocode:
INDR = r1
if (r2 == Even Numbered) :
INCR = r2
LIMR = r2+1
else if (r2 == Odd Numbered):
INCR = r2
LIMR = r2
|
Once these three are identified, working of both these instructions
can be understood below:
BXLE:
|INDR| = |INDR|+|INCR|
if (|INDR| <= |LIMR|) take a branch to D(B)
else go to next instruction
1. Condition code remains unaltered.
BXH:
|INDR| = |INDR|+|INCR|
if (|INDR| > |LIMR|) take a branch to D(B)
else go to next instruction
1. Condition code remains unaltered.
|
CREATING INTERNAL SUBROUTINES
Succession of logical steps for calling a subroutine is summarised below:
1. Store the address of next instruction in some register.
2. Take a branch to the address where subroutine begins.
3. Once there, store all the registers to an area in memmory
4. Perform the tasks coded into the subroutine
5. At the end, restore all registers from area in Step:3
6. Take a branch to main program using information stored in Step:1
|
The Steps 1,2 can be implemented using either of following instructions:
BAL r,D(X,B)
BALR r1,r2
Pseudocode:
BAL:
|r| = |PSW (right 32 bits)|
take a branch to D(X,B)
BALR:
|r1| = |PSW (right 32 bits)|
if (r2 != R0) take a branch to |r2|
else go to next instruction
|
The
BAL
instruction cause right 32 bits of PSW which contain
the address of next instruction, to be stored in 'r' register. Then a
branch is taken to the address D(X,B), which in current context is the
address of subroutine we wish to call. The
BALR
instruction
is similar to
BAL
, except that the branching takes place
into the address contained in
r2
and that if
r2
is R0, branching does not take place.
Upon being called, a subroutine needs to store caller's data before
using any of the registers, so that they may be restored upon exit.
This constitute steps 3 and 5, and may be implemented with following
instructions:
STM r1,r2,D(B) :STORE TO MEMMORY
LM r1,r2,D(B) :LOAD FROM MEMMORY
Pseudocode:
STM:
Store registers r1 through r2 into 1 FW each
of the contiguous memmory starting D(B).
LM :
Restore registers r1 through r2 from contiguous
memmory starting at D(B), reading 1 FW into each.
*NOTE: Note address is coded as D(B): X not allowed !!
|
Here we show a pseudocode to demonstrate the call to an
internal subroutine:
***********************************************************
*MAIN FUNCTION: CALLER DEMO *
*R6: CONTAINS ADDRESS OF NEXT TO CALLER *
***********************************************************
MAIN CSECT :CONTROL SECT
USING MAIN,15 :ESTABLISH BASE REG
BAL R6,SUBR :STORE NEXT INSTR,
* AND BRANCH TO A(SUBR)
BR R14 :EXIT
***********************************************************
*SUBROUTINE SUBR: DEMO SKELETON *
*R6: CONTAINS ADDRESS OF NEXT TO CALLER *
***********************************************************
SUBR STM R0,R15,SUBSAFE :STORE REGS INTO MEMMORY
... .............. :DO STUFF
... .............. :DO STUFF
LM R0,R15,SUBSAFE :RESTORE REFS FROM MEMMORY
BR R6 :BRANCH BACK TO CALLER
LTORG :LITERALS STORAGE
SUBSAFE DS 18F :RESERVE REG STORAGE
END MAIN :END MAIN
|
Its time to finish the current post here, please take time to post
your comments or suggestions below. If you have any example code, feel
free to share that as well.
No comments:
Post a Comment