Unit 7.7 -- Demonstrate External Subroutines
Prog
Subroutine Swaps two Numbers
PED
Learn how to set up external subroutines
Concepts
To call external routine
L 15,=V(rname)
...
BALR register,15
To load and debug
LOAD file1 file2 (reset name1
file1 = name of first file
file2 = name of second file
name1 = name on start statement ofmain program
80.html
81.html
Unit 7.7 External Subroutines
Let's say one has a long program. Let's say its tens of
thousands of lines, perhpas even millions of lines long. So
far, we have only learned how to deal with such a program by
putting it in a single file. Every time, we make a slight
change to any line in any of the subroutines, we would have
to compile the whole thing. This could take a long time.
We would like to avoid having to compile all 10,000 or all
ten million lines of a program, every time we run the
program.
We do this by using external subroutines. That is, we have
two (or more) files, each of which contains part of the
program. Generally, each distinct subroutine would be in a
separate file. It will be an ASSEMBLE file.
We need some method of linking these together.
Specifically, there are times when a lable might be used in
one file (or subroutine) and the lable itself is defined in
another file. When we load both of the programs, somehow
the system must realize that these two lables are in fact
the same thing.
Lables that we specify in the form
label CSECT
ENTRY label
label START
Thus, if I wrote BLAH CSECT or ENTRY BLAH in a assembler
program file, then other assembler files loaded together can
also branch to or load or store from BLAH.
These lables are known as external variables--the word
"external" meaning "external" to this source file.
The other thing that I want to be able to do is to refer to
one of the above lables. I do this by using a V-Type
constant or the word EXTRN. When, I write =V(lable), then
I can write L register,=V(label) and that is like LA
register,label. However, label will be defined in some
other ASSEMBLE file.
We could also write EXTRN label. In that case the label
would be used like any other variable in the program written
in that ASSEMBLE file. Using ENTRY in one program and EXTRN
in another will allow us to create global variables that can
be used in separate ASSEMBLE files, separate external
subroutines.
Each ASSEMBLE file is assembled by writing HASM and the
name. Thus, if a given program consisted of three
subroutines, each in a separate ASSEMBLE file, one would
issues three separate HASM commands--one for each ASSEMBLE
file.
Then to run the program we type the LOAD command as we
normally do. However, we include each name in the load.
Thus, if we had our complete program in files ZING ASSEMBLE,
ROTGUT ASSEMBLE, SMITH ASSEMBLE, we would type the following
to completely assemble and run our program
HASM ZING
HASM ROTGUT
HASM SMITH
LOAD ZING ROTGUT SMITH
The loader will for each
=V reference
EXTRN lable
track down the corresponding ENTRY, CSECT or START
statement. Then, it will put the address from the ENTRY or
CSECT or START statement in the instructions using the
lable. This is called linking.
Our sample program is a modification of an earlier program--
to illustrate setting up external subroutines. The original
program can be found in section 7.2 on page 163. The
subroutine BLAH is moved to a separate routine. Let us look
at this subroutine (found on page 199). Observe the "blah
csect" on line 2. It lets the loader know that "BLAH" can
be found here." Observe also that we have to independently
establish addressability. We have the familiar "BALR 12,0"
and "USING *,12"
The main program is found before this on two pages. Note
the first call found on lines 34 to 35. Particularly note
the "+V(BLAH)" which stands for the address of BLAH. The
loader will ensure the address of BLAH on page 199 is loaded
by this instruction. There is one little peculiarity worth
mentioning. These are the "LR 9,12" and "LR 12,9" on lines
32 and 36. These save register twelve which is modified in
the BLAH subroutine.
One more note concerns debugging the program. When we LOAD
one or more ASSEMBLE files, a file called "LOAD MAP" is
produced. It gives the address in memory where each
subroutine (or whatever) can be found. The first one would
be loaded at 20000. The others are loaded elsewhere. To
refer to the address in a DISPLAY statement or PER INSTRUCT
RANGE statement to the debugger, we add the address given by
LOAD MAP to the offset in the listing. This is a general
case of adding the familiar 20,000.
Here is an example of a LOAD MAP FILE:
P1 SD 00020000 RMODE 24 AMODE 24
BLAH SD 000200E0 RMODE 24 AMODE 24
This says that the main program "P1" is at 20000 (hex). The
subroutine BLAH is at 200E0. If we wanted to put a break
point at the instruction "L 2,8(0,1)" at 20010, we would
write PER INSTRUCT RANGE 200F0. 200F0 is the result of
adding the 200E0 where BLAH begins to the offset 10 from the
listing.