Previous PageTable Of ContentsIndex


7 PROGRAMMING AND RUNNING TIPS

7.1 Modular Programming

7.2 Program Commenting

7.3 Standard Binder Conventions

7.4 Register Usage

7.5 Some Coding Hints

7.5.1 General Programming Guidelines

7.5.2 Instruction Usage Hints

7.6 Data Formats for Inter-Language Communication


Icon7 PROGRAMMING AND RUNNING TIPSIcon

The suggestions in this section apply to Assembler Language jobs run at NIH.

7.1 Modular Programming

Modular programming may be defined as a method of dividing problem solutions into logical parts so that they may be solved by arranging programs into sections which are easily understood and written. The result of this method of program design is a group of related routines controlled by a single routine called a "main line" or "driver" program. Using this method, routines may be added, deleted, or modified without affecting the remainder of the program; routines may be used in several different places within a program without duplicate coding; and sections may be coded and tested independently. The primary objectives of modular programming are an increase in ease of understanding and modification and standardization of program organization. When writing modular programs:

· Each routine should establish its own base register for addressability.

· All called routines should return to an address supplied by the calling routine.

· Standard OS/VS Binder conventions should be followed.

7.2 Program Commenting

One of the most useful tools available for maintaining programs is the existence of meaningful comments on a program listing. Comments should be written to explain what takes place in a program rather than to act as extraneous words on a listing. It is very helpful to precede programs with commentary explaining:

· purpose of the routine

· the action that takes place and the method used

· conditions assumed or expected upon entry; i.e., register contents, parameter list structure, etc.

· conditions set upon exiting from the routine

· other routines that call and are called by this routine

In addition to prologue commentary, instruction coding should be documented. These comments may point out restrictions, techniques, cautions, etc. that one should know before attempting to modify the program. For ease of reading, all in-line commentary should start in the same column.

7.3 Standard Binder Conventions

It is the responsibility of a calling routine, whether the user's program or the operating system, to:

· insert the entry point address of the called routine in general register 15

· insert the return address in general register 14

· insert the address of an 18 word save area in general register 13

· insert the address of a parameter list (if any) in general register 1

It is the responsibility of the called routine to:

· save the contents of all of the caller's general registers upon entry

· restore the contents of the caller's general registers immediately before returning

· return to the address supplied by the calling routine

A detailed description of OS/VS Binder conventions, save areas, and parameter lists may be found in the publication, IBM MVS/ESA Programming: Assembler Services Guide, GC28-1466

7.4 Register Usage

General registers 0,1,13,14, and 15 are known as the linkage registers and are used in a prescribed manner by the Operating System. These registers should be used in the same manner by the problem program in order to avoid the possibility of register clobbering.

Registers 0,1,14, and 15 may be altered by the Operating System when using system macro instructions. Registers 2-13 remain unchanged.

Registers 0 and 1 are used to pass parameters or parameter lists between programs.

Register 13 contains the address of the save area the user provided. This save area may be used by the Operating System for any function the program requests.

Register 14 contains the return address of the program that called the user's routine, or an address within the operating system to which it is to return when it has finished processing.

Register 15 contains an entry point address when control is passed to a program from the Operating System. The entry point should be in register 15 when control is passed to another program or subroutine. Register 15 is also used to pass a return code to the calling program. When control is returned to OS, the contents of register 15 will be the condition code returned for the job step.

7.5 Some Coding Hints

The purpose of this section is to define some general rules and unusual uses of instructions that will help the programmer conserve storage and CPU time.

7.5.1 General Programming Guidelines

· At no time should a program be written which modifies the contents of an instruction during program execution. This makes maintenance unduly burdensome and may create model dependent code since the manner of instruction decoding and execution varies among different models of System 370. Instead, the EX (execute) instruction can be used to alter an instruction during execution.

· Whenever possible, arithmetic and internal data representation should be done in fixed point binary rather than packed or zoned decimal. Decimal instructions and data require more storage and CPU execution time.

· Programs should be planned to keep data movement to a minimum. Data movement can often be avoided by passing an address in a register rather than the actual data from routine to routine.

· When defining constants, place items requiring double-word alignment first, followed by full-word items, followed by half-word items, followed by items that do not require any boundary alignment.

· Do not attempt to capitalize on unique characteristics of individual operating system implementations. Programs written to take advantage of specific hardware or software features tend to be much more difficult to test and maintain.

· Emphasize reduction of short term storage requirements even though the total size of the program may increase slightly. The primary objective is to shrink and stabilize the working set of each significant phase of the program. Although size limits will always be enforced at the Computer Utility, the total size of the program is of less consequence since only the active portion of the program requires real storage.

· Optimize the main line of the program for the normal case. Remove all exception and error handling routines from the normal program flow. This will increase the density of reference of the most heavily used pages. However, these conditions should be detected in the main line to avoid unnecessary entry into another page. The actual error routines should be grouped together in pages of their own since under normal circumstances they will never be entered. Low use code that is not exception handling code should be inline (i.e., housekeeping and initialization) unless these routines are so large that good density cannot be maintained.

· Segment programs that have long running, well defined phases by function even if some code must be duplicated. This will improve working set stability.

· Remember that locality of reference applies only to the working set. The important consideration is to keep storage references confined to pages that would normally tend to be in main storage at the same time. It is logically immaterial whether the working set consists of contiguous pages or of pages scattered throughout the program. However, experience has shown that internal fragmentation is reduced (and program readability is improved) if the working set consists of contiguous pages.

· Initialize each data area just prior to its use rather than at the beginning of the program. This will tend to prevent unnecessary paging activity. In addition, if a large area of virtual storage is reserved for handling a worst case situation, do not initialize it until the exact size needed is determined.

· High use data areas and I/O buffers may be grouped together in common storage using the COM assembler instruction. This allows convenient ways of aligning these areas on specific page boundaries if needed.

· Align large buffers on page boundaries. Buffer areas are "fixed" in main storage during I/O operations. Careless buffer alignment could cause additional pages to be needed. From a paging viewpoint, the optimal size for I/O buffers is the length of a page (or a multiple thereof).

· If possible, separate read only data areas from areas that will be changed. This could save page out operations since only those pages that are changed are rewritten to external storage. Bear in mind, however, that good locality is usually more important than strict separation of read-only and read-write areas.

· Order subroutines that are needed together or that are nested. For example, if the main program invokes subroutines A, B, and C, or if A calls B which in turn calls C, then place A, B, and C together.

· Consider segmenting very large arrays and data areas into page size units. Then process each segment instead of the entire array.

· Literals (including literal address constants) may be inserted into the same page where they are referenced. This can be accomplished by judicious use of LTORG statements that can be placed at the end of each functional routine. This also helps to attain "readability" of a program - something that is often non-trivial.

· In a multi-processor environment where multiple tasks may be running concurrently in the same job, any data that is accessed from more than one task should be serially referenced to avoid simultaneous access. Simultaneous access may yield incomplete changes.

· If SORT is called from the Assembler and Computer Center procedures are not being used, the following statement must be included for the SORT/MERGE program messages:


  //stepname.SORTMSGS DD SYSOUT=A

7.5.2 Instruction Usage Hints

Here are some examples of instruction usage. Any contributions to this section by experienced programmers would be warmly welcomed.

· When RX type instructions are used for data not covered under a USING statement, an index register should always be specified even if it is not being used. If no indexing is being used, indicate its absence by coding a comma (,) or specify register 0 as the index register preceding the B2 specification. Omitting the comma causes the Assembler to assume the B2 specification is an X2 specification and the instruction is assembled with no base register assigned. Although the instruction will work, it requires more execution time because of the added cycles for indexing and can cause confusion when debugging.

Example:

      L  R4,0(,R6) is faster than  L  R4,0(R6).

· Branch on Count (BCTR)

This instruction is generally used to decrement the contents of a register (R1) being used as a counter and branch to the address contained in R2 when the counter is non-zero. This instruction may be used to decrement the counter without branching by specifying register zero for the R2 field. This can be quite useful to prepare a register for the object of an EXECUTE instruction.

              LA    R5,L'FIELDA      GET LENGTH OF FIELDA
              BCTR  R5,0             GET MACHINE LENGTH
              EX    R5,MOVE          EXECUTE THE MOVE
              .
              .
              .
        MOVE  MVC   FIELDB(1),FIELDA

· Load Address (LA)

Normally this instruction is used to load a register with the address of some data or instruction. However, it may also be used to load a register with an absolute value between 0 and 4095, or to increment a register by an absolute value between 0 and 4095. Load address may also be used to set the high order byte of a register to zero.

· Shifting Instructions

To multiply or divide by a power of 2, use a shift instruction instead of the multiply or divide instruction. For example, to divide a number in register 4 by 8, code


   SRL R4,3 DIVIDE BY 8

The number of shift positions equals the power of 2 by which the register is multiplied or divided.

· SAVE macro

The SAVE macro may be coded with an identifier name of up to 70 characters. When using subroutines, it is a good idea to use this form of the SAVE macro so that each subroutine may be easily located in a dump by using the EBCDIC translation at the right side of the dump. Version number and date may be coded with the CSECT name as part of this identifier, as illustrated below:

        SAVE (14,12),T,SORTER-V7-4OCT88

· Return codes

Each Assembler language main program or subroutine should set the return code in register 15 prior to returning control to the operating system or calling program. The RC parameter of the RETURN macro may be used. If register 15 is not properly set, a garbage condition code may appear for the job step.

· ANDs and ORs

      A  exclusive-ored  B
      B  exclusive-ored  A
      A  exclusive-ored  B

7.6 Data Formats for Inter-Language Communication

The following tables show the ways data can be stored. The source language definitions for each data type are given under the COBOL, FORTRAN, and PL/I headings. For more specific information on data formats, consult the appropriate language manuals and the IBM ESA/390 Principles of Operation, SA22-7201.

The "MACHINE DATA FORMAT" column in the figures below shows a bit breakdown of the data type as stored internally. Bit positions are written vertically under the machine data format symbols they refer to.

CHARACTER

COBOL

FORTRAN

PL/I

TYPE

PIC X(n)

DISPLAY

1<=n<=32767

CHARACTER*n

1<=n<=3267

CHAR(n)

1<=n<=32767

Length =

n bytes

MACHINE DATA FORMAT

EXAMPLE

Char 1

Char 2

...

Char n

Value

Internal hex

representation

0 0

-

0 7

0 1

-

8 5

   

ABCD

C1C2C3C4

Figure 2. Character Formats for Inter-Language Communication

FIXED POINT

The fixed point two-word data type, which is available only in COBOL, is simulated through software and requires all data items to be aligned on a word boundary.

The "Range" given in the table indicates the minimum and maximum values numbers can have in all uses of the language. Idiosyncrasies in languages reduce the full range of numbers in some cases even though they are represented the same internally.

Assumed decimal points in COBOL and PL/I are not shown in the table. They are stored in the same way as other numbers; instructions generated by the compilers keep track of the position of the assumed decimal point.

COBOL

FORTRAN

PL/I

TYPE

PIC S9(1-4)

COMP

(or COMP-4)

Range:

-9999 to 9999

INTEGER*2

Range:

-32768 to 32767

FIXED BIN

(1-15,0)

Range:

-32768 to 32767

Halfword

Length = 2 bytes.

PIC S9(5-9)

COMP

(or COMP-4)

Range:

-(9)9s to +(9)9s

INTEGER*4

Range:

-2147483648 to

2147483647

FIXED BIN

16-31,0)

Range:

-2147483648 to 2147483647

Fullword

Length =4 bytes.

PIC S9(10-18)

COMP

(or COMP-4)

Range:

-(18)9s to +(18)9s

-----

-----

Two-word

Length = 8 bytes.

Figure 3. Fixed Point Formats for Inter-Language Communication

MACHINE DATA FORMAT

EXAMPLES

    0 0 - 1

    0 1 5 Halfword

Value

----------+1234

-1234

Internal hex
representation

--------------------

04D2

FB2E

0 0 - 3

0 1 1 Fullword

+1234

----------

-1234

000004D2

---------------------

FFFFFB2E

0 0 - 6

0 1 3

Two-word

+1234

----------

-1234

0...04D2

---------------------

F...FB2E

"S" is a binary sign bit: 0 is positive; 1 is negative.
"I" is a 15, 31, or 63 bit integer.
Figure 3
(Continued)

FLOATING POINT

Magnitude is the range of a number expressed in powers of ten.

Although the numbers are represented the same internally, peculiarities in languages reduce the precision of numbers in some cases. The degree of precision given in the table is good in all cases. Fractional precisions occur because of the difference between the decimal representation and the machine's internal storage of numbers.

COBOL

FORTRAN

PL/I

TYPE

COMP-1

Magnitude:

10**-78 to 10**75

Precision:

7.2 digits

REAL*4

Magnitude:

10**-78 to 10**75

Precision:

7.2 digits

FLOAT

DEC(1-6)

Magnitude:

10**-78 to 10**75

Precision:

6 digits

Short

Length = 4 bytes

COMP-2

Magnitude:

10**-78 to 10**75

Precision:

16 digits

REAL*8

Magnitude:

10**-78 to 10**75

Precision:

16.8 digits

FLOAT

DEC(7-16)

Magnitude:

10**-78 to 10**75

Precision:

16 digits

Long

Length = 8 bytes

------

REAL*16

Magnitude:

10**-78 to 10**75

Precision:

35 digits

FLOAT

DEC(17-33)

Magnitude:

10**-78 to 10**75

Precision:

33 digits

Extended

Length = 16 bytes

Figure 4. Floating Point Formats for Inter-Language Communication

MACHINE DATA FORMAT

EXAMPLES

0 0-0 0 - 3

0 1 7 8 1

Short

Value

-----------

+1234

------------1234

Internal hex

representation

---------------------

434D2000

---------------------

C34D2000

0 0-0 0 - 6

0 1 7 8 3

Long

+1234

-----------

-1234

434D20...0

---------------------

C34D20...0

0 0-0 0 - 6

0 1 7 8 3

0 - 0 0 6

0 7 8 3

Extended

+1234

-----------

-1234

434D20...0

---------------------

C34D20...0

"S" is a binary sign bit: 0 is positive; 1 is negative.
"E" is a seven bit exponent with a value between hex 16** -64 and 16** +63.
"F" is a fraction, which may be 24, 56, or 112 bits long.
Figure 4
(Continued)

ZONED DECIMAL

The "Range" given in the table indicates the minimum and maximum values numbers can have in all uses of the language. Idiosyncrasies in languages reduce the full range of numbers in some cases even though they are represented the same internally.

COBOL

FORTRAN

PL/I

TYPE

PIC 9(n)

DISPLAY

1<=n<=18

Range: 0 to (18)9s

------

PIC '(n)9'

1<=n<=15

Range: 0 to (15)9s

Unsigned

Length = n bytes.

PIC S9(n)

DISPLAY

1<=n<=18

Range:

-(18)9s to +(18)9s

------

PIC '(n-1)9T'

1<=n<=15

Range:

-(15)9s to +(15)9s

Signed

Length = n bytes.

MACHINE DATA FORMAT

EXAMPLES

0-0 0-0 0-1 1-1

0 3 4 7 8 1 2 5

Unsigned

Value

----------

1234

Internal hex

representation

---------------------

F1F2F3F4

0-0 0-0 0-1 1-1

0 3 4 7 8 1 2 5

Signed

+1234

----------

-1234

F1F2F3C4

---------------------

F1F2F3D4

"Z" is a 4 bit zone code with a value of hex F.
"D" is a 4 bit binary decimal number with a value between hex 0 and 9.
"Si" is a 4 bit sign code: A, C, E, and F are positive; B and D are negative.

Figure 5. Zoned Decimal Formats for Inter-Language Communication

PACKED DECIMAL

The "Range" given in the table indicates the minimum and maximum values numbers can have in all uses of the language. Idiosyncrasies in languages reduce the full range of numbers in some cases even though they are represented the same internally.

COBOL

FORTRAN

PL/I

TYPE

COMP-3

PIC 9(n)

1<=n<=18

Range: -(18)9s to +(18)9s

------

FIXED

DEC(n)

1<=n<=15

Range: -(15)9s to +(15)9s

Length in

bytes = (n+1)/2 rounded up.

MACHINE DATA FORMAT

EXAMPLES

0-0 0-0

0 3 4 7

Value

---------------

-1234

---------------

-1234

Internal hex

representation

---------------------

01234C

---------------------

01234D

"D" is a 4 bit binary decimal number with a value hex 0 through 9.
"Si" is a 4 bit sign code: A, C, E, and F are positive; B and D are negative.

Figure 6. Packed Decimal Formats for Inter-Language Communication


Using Assembler Language at the NIH Computer Center - September 1998
Comments

Previous PageTop Of PageTable Of ContentsIndex