You are on page 1of 194

DAVID WOOLBRIGHT'S WEB PAGE

Contents
CPSC 3121/3122 Resources

Assembler Concepts Powerpoint Lectures

General Articles on Programming in Assembler

The following is a list of links to articles covering a variety of topics in IBM System/390 Assembly language.

1. Conversion of Binary, Decimal, and Hexadecimal Data


2. System 390 Architecture
3. Character Data
4. Packed Decimal Data
5. Binary Data
6. The Define Constant Directive
7. Data Conversions
8. Organizing a Simple Assembler Program
9. Sequential File Processing (QSAM Files)
10. Loops
11. Packed Decimal Arithmetic
12. Base Displacement Addressing
13. Dsects
14. Explicit Addressing
15. Instruction Formats
16. Program Linkage
17. Address Constants
18. Assembler Course PowerPoints

Video Instruction in Assembler - a video course I am building

Introduction to Assembler Language


SS1 Instructions, MVC, CLC, MVI
MVI, DCB, Open, Close, Standard Entry and Exit
A First Program
Removing Assembly Errors in the First Program

Notes On Individual System Z Instructions

The following table is a collection of links to individual articles covering all the major instructions (used by
application programmers) in the IBM System 390 architecture. Each article contains a description of the instruction,
example uses of the instruction, and "tips" on technique.
A AH AP AR BAS BASR BC BCT BCTR CLC
CLI CH CP CR C CVB CVD D DP
DR ED EDMK EX IC ICM L LA LCR
LM LNR LH LPR LR LTR M MP MH
MR MVC MVCL MVI MVN MVZ N NC NI
NR O OC OI OR PACK S SLA SLDA
SLDL SLL SRA SRDA SRDL SRL SRP ST STC
STH STM SH SP SR TM TR TRT UNPK

http://csc.columbusstate.edu/woolbright/WOOLBRIG.htm[9/21/2011 4:21:45 PM]


DAVID WOOLBRIGHT'S WEB PAGE
Contents
X XC XI XR

http://csc.columbusstate.edu/woolbright/WOOLBRIG.htm[9/21/2011 4:21:45 PM]


Contents

 
     One of the basic skills a programmer needs is the ability to convert numbers between decimal, hexadecimal, and binary.  This
article will demonstrate the conversions between each of these bases.
 
Decimal to Hexadecimal
 
   Here is an algorithm to convert a decimal integer to hexadecimal:
 
1)      Let X be the decimal integer you wish to convert and let k = 1.
 
2)      Divide X by 16, saving the quotient as Q, and the remainder (in hexadecimal) as R k .
 
3)      If Q is not zero, let X = Q, k = k + 1, and go back to step 2. Otherwise go to step 4.
 
4)      Assume steps 1-3 were repeated n times.  Arrange the remainders as a string of digits -  R n R n-1 R n-2 …R 3 R 2 R 1 .
 
   Here is an example where we number and describe each iteration of the algorithm:
 
1)      Let X = 954 and let k = 1.  Dividing by 16 we have Q = 59 and R 1 = A (10 = A in hexadecimal).  Since Q is not zero, we let X
= 59 and go back to start the second iteration.
 
2)      Dividing X = 59 by 16, we have Q = 3 and R 2 = B since 11 = B in hexadecimal.  Since Q is not zero, we let X = 3 and start
the third iteration.
 
3)      Dividing X = 3 by 16, we have Q = 0 and R3 = 3.  Since Q = 0, the loop terminates and the algorithm is completed by
arranging the remainders as “3BA”.
 
   Here is another example using long division.  In this example we convert 2623 in decimal to A3F in hexadecimal.  The
computations move from right to left.
 

 
 
Hexadecimal to Decimal
 
   Consider the problem of converting the hexadecimal number A3B7 to decimal.  Each hexadecimal digit in the representation
represents a number of occurrences of a power of 16.  We can change each hexadecimal digit to its decimal equivalent and
multiply by the corresponding power of 16.  Totaling the components produces the decimal representation of the original
hexadecimal number.

http://csc.columbusstate.edu/woolbright/CONV.HTM[9/21/2011 4:21:47 PM]


Contents
 
           A = 10 x 16 3 = 10 x 4096 = 40960
           3 =  3 x 16 2 =  3 x  256 =   768
           B = 11 x 16 1 = 11 x   16 =   176
           7 =  7 x 16 0 =  7 x    1 =     7
                              Total = 41911
     
  Here is another example in which 3FB9 is converted to decimal.
 
           3 =  3 x 16 3 =  3 x 4096 = 12288
           F=  15 x 16 2 = 15 x  256 =  3840
           B = 11 x 16 1 = 11 x   16 =   176
           9=  7 x 16 0 =   9 x    1 =     9
                              Total = 16313
     
Decimal to Binary
 
   When a number is expressed in binary, each 1 in the expression represents a power of 2 ( 1, 2, 4, 8, …).  Perhaps the faster
way to convert from decimal to binary involves removing successive powers of two (starting with the largest and proceeding to the
smallest) from the decimal number.  Each time we are able to remove a power of 2, we record a 1 in the binary representation. 
Each time we are unable to remove a power of 2, we record a 0 in the binary representation.  The operation proceeds from left to
right.  Consider the problem of converting the decimal integer 115 to binary.  The largest power of 2 which can be removed from
115 is 2 6 = 64.  Removing 64 leaves 115 - 64 = 51.  We record the removal of 64 as a 1 in the leftmost digit of the binary
representation (1…).  Next we remove 32 from 51.  This leaves 51 - 32 = 19, and we record another 1 in the binary representation
( 11…).  Continuing, we remove 16 from 19 leaving 3, and we record another 1 ( 111…).  The next two powers of 2 are 8 and 4. 
These cannot be removed from 3 and so we record 0 in the next two positions (11100…).  Next we remove 2 from 3 and then 1
from 1, recording 1 in the last two positions (1110011). 
 
   Here is an illustration where the decimal integer 82  is converted to the binary representation “1010010”.  The computation
proceeds from left to right with the successive removal of powers of 2.  Notice that when a power of 2 is successfully removed it
causes a “1” to occur in the binary representation.  When we are unsuccessful, a “0” appears.
 

 
Binary to Decimal
 
   In the representation of a binary integer, each 1 indicates the occurrence of the corresponding power of 2.  To convert to
decimal, we simply compute the total of the powers of 2 which correspond to a 1.  Consider the following example in which we
convert 1101110 to a decimal representation.
 
           1 = 1 x 26 =  64
           1 = 1 x 25 =  32
           0 = 0 x 24 =   0
           1 = 1 x 23 =   8
           1 = 1 x 22 =   4
           1 = 1 x 21 =   2
           0 = 0 x 20 =   0
                Total = 110    
 
 
   Here is another example in which 100111 is converted to 39 in decimal.
 
 
5

http://csc.columbusstate.edu/woolbright/CONV.HTM[9/21/2011 4:21:47 PM]


Contents
           1 = 1 x 2 =  32
           0 = 0 x 24 =   0
           0 = 0 x 23 =   0
           1 = 1 x 22 =   4
           1 = 1 x 21 =   2
           1 = 1 x 20 =   1
                Total =  39    
 
 
 
Hexadecimal to Binary
 
   Base 16 and base 2 are “compatible” bases since 16 is a power of 2.  This makes the conversion from hexadecimal to binary
quite easy:  Replace each hexadecimal digit with its four-bit binary representation.  Here is an example in which the hexadecimal
number AB9F3C is converted to 101010111001111100111100.
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
Binary to Hexadecimal    
 
   Converting from binary to hexadecimal involves replacing each consecutive block of four bits in the binary representation (moving
from right to left within the representation) with its hexadecimal equivalent.  You may need to add 0’s on the left of the binary
representation in order that the number of 1’s and 0’s is a multiple of 4.   Consider the following conversion.

Each block of four bits beginning with 1010 is replaced with one hexadecimal digit.  The leftmost 2 digits 11 are treated as 0011
and converted to “3”.
 
 

http://csc.columbusstate.edu/woolbright/CONV.HTM[9/21/2011 4:21:47 PM]


Contents

 
   The term “machine architecture”  refers to the design of the electronic components that comprise a computer.  Since we are
studying assembly language, we are most interested in the design of the components that directly affect the assembler programs
we write.  These components include Memory, Registers, the Program Status Word, and the CPU.  The orginal architecture was
designed in the early 1960’s and was know as the System 360.  The “360” in the name referred to 360 degrees - the number of
degrees in a circle.  (System 360 machines were supposed to be be “all-purpose” machines, capable of handling business as well
as scientific applications. )  In the early 1970’s the architecture was modified to allow access to larger amounts of memory and was
known as the System 370 architecture.  The architecture has continued to evolve and today is known as the System 390. 
Throughout this evolution, the architecture has remained “backwards compatible”.  In fact, programs that were written to run on
1960’s era machines can run on current machines with little or no change in their code.  The IBM mainframe has been an
incredibly stable platform and this fact has accounted for much of the success of this family of machines.   We begin our discussion
of the architecture by looking first at the main storage memory of the machine.
 
MEMORY
 
   The smallest unit of storage memory is a bit (binary digit).  A bit can hold a binary digit, 0 or  1, and is represented internally in
the machine as a high or low voltage.  Bits are organized into consecutive groups called bytes.  In the System 390 architecture, a
byte consists of 8 bits together with a “hidden” ninth bit that is used for parity checking.  Since the parity bit is unavailable to us as
programmers, we will assume that there are 8 bits in a byte.  With 8 bits there are 2 8 = 256 possible bit patterns that can be made.
 
 
                           Binary Pattern        Decimal Equivalent
 
                                00000000      =              0
                                00000001      =              1
                                00000010      =              2
                                00000011      =              3
                                00000100      =              4
                                    ...
                                11111101      =            253
                        11111110      =            254
                                11111111      =            255
 
Each of the 256 bit patterns is used to represent one character of data in the EBCDIC encoding sequence.  “EBCDIC” is an
acronym for “Extended Binary Coded Decimal Interchange Code”.  This is a fancy name for a code created by IBM to represent
characters in memory.  For instance 11000001 represents a character “A” , and 11110001 represents a character ‘1’ in the
EBCDIC encoding sequence. “ASCII” is another binary code which is used on non-IBM machines.   See the article on Character
Data for more details.
 
 
 
 
   Each byte can be divided into two 4-bit areas called the zone and numeric portions as pictured below.  Programmers will refer to
a half-byte as a “nibble”  or sometimes “nybble”.  This is a colloquial term that is not found in the IBM documentation. 
Nevertheless,  bits 0 - 3 are called the “High Order Nibble” and bits 4 - 7 are called the “Low Order Nibble”.
 
 

http://csc.columbusstate.edu/woolbright/ARCHITEC.HTM[9/21/2011 4:21:48 PM]


Contents

             
 
   Bytes are arranged consecutively and numbered, starting with the first byte, which is numbered 0 as indicated in the diagram
below.  The number assigned to each byte is called an address.  The idea of an address is an important one when learning to
program in assembly language since every reference to memory is made using an address.  This idea will be thoroughly developed
in the article on Base/Displacement Addressing.
 

                       
   A byte is the smallest unit of storage on the machine that has an address.  Bits do not have addresses.
 
   Consecutive bytes are arranged into groups called fields.  The address of a field is denoted by the address of the first byte that
is in the field.   A halfword is a 2-byte field that begins on an address that is evenly divisible by 2 ( Addresses 0, 2, 4, 6, ...).  Such
an address is called a halfword boundary.  A fullword is a 4-byte field that begins on a fullword boundary (an address evenly
divisible by 4).  A doubleword is an 8-byte field that begins on a doubleword boundary (an address that is evenly divisible by
8).  In the diagram above there are 3 halfwords pictured (bytes 0 and 1, bytes 2 and 3, and bytes 4 and 5), 1 fullword ( bytes
0,1,2, and 3 ), and the beginning of a doubleword ( bytes 0 - 8).
 
 
There are several terms that are commonly used to describe blocks of memory:
 
                             1)   kilobyte    = 2 10 = 1,024 bytes
                             2)   megabyte =220 = 1,048,576 bytes
                             3)   gigabyte   =230 = 1024 megabytes
 
  The original System 360 architecture, which was designed in the early 1960’s, called for a 24-bit address size when referring to
bytes in main storage.  With 24 bits, the maximum address which could be constructed (24 consecutive binary 1’s) is 2 24 - 1 = 16
megabytes.  The architecture was extended in the 1970’s in order to support 31-bit addresses.  Today,  the machine is capable of
creating addresses as large as 2 31 - 1 = 2 gigabytes.
 
 
 
 
REGISTERS
  
   A register consists of special circuitry devoted to high speed arithmetic, addressing main storage locations, and providing control
information for the operating system.  There are  3  types of registers:
 
   1)  General purpose -  There are 16 general purpose registers numbered 0 through 15 that are available to an assembler
programmer.  These registers are used for high-speed arithmetic and addressing storage locations.  Each general purpose register
is 32 bits in length - just large enough to hold a fullword.
 
   2)  Floating point -  There are 4 floating point registers available for an assembler  programmer.  These registers are used for
scientific data processing where the data is quite large or has a large number of decimal places.  Each floating point register is 64
bits in length.
 
   3)  Control - There are 16 control registers used by the operating system to control the operation of the machine.  These

http://csc.columbusstate.edu/woolbright/ARCHITEC.HTM[9/21/2011 4:21:48 PM]


Contents
registers are not available to an application programmer.  Each control register is 32 bits in length.
 
   We are most interested in learning about the general purpose registers since these are heavily used by application
programmers.  In fact, we will assume that the term “register” refers to the term “general purpose register” unless otherwise
specified.
 
PROGRAM STATUS WORD (PSW)
 
   The Program Status Word or PSW is a collection of 64 bits that are used to indicate the current status of the machine.  There are
numerous fields in the PSW  and two of these fields are of special importance to an assembler programmer:
 
   1)   Condition Code -  This is a 2 bit field that is used to indicate the results of a comparison operation or an arithmetic
operation.  The condition code has four settings since it is a 2-bit field  ( equal - 00, low/minus - 01, high/positive - 10, overflow -
11 ).  After the condition code is set, it can be tested with a branch instruction.  Here is an example,
 
 
                   CLC   OLDCOST,NEWCOST   SET THE CONDITION CODE   
                   BE   THERE              TEST THE CONDITION CODE
 
 
The first instruction is a “Compare Logical Character” instruction which compares the two fields OLDCOST and NEWCOST.  This
has the effect of setting the bits in the condition code.  Subsequently, the condition code is tested with the second instruction
which is called  “Branch Equal”.  This instruction examines the condition code and causes execution to continue at the label
“THERE” if the two fields are equal.
 
   2)  Instruction Address - This is a 31-bit field that contains the address of the next instruction that the machine will execute. 
The address of the instruction is used in a process that is called the “Fetch/Execute” cycle.  This process describes, algorithmically,
how a computer operates.  The Fetch/Execute cycle is a “loop” which the CPU continually executes.  The cycle consists of the
following 5 steps:
 
                  1)   Fetch the instruction whose address is in the PSW instruction address field.
 
                  2)  Decode the instruction which was fetched.
 
 
                  3)  Update the PSW instruction address field so that it points at the next
                       instruction in the program.
 
                  4)   Execute the decoded instruction.
 
                  5)   Go back to step 1.
 
 
  Cycling through the Fetch/Execute cycle, the machine usually executes instructions in a sequential fashion.  There is one
exeception to this which occurs when the CPU executes a branch instruction.  In this case, if the branch is sucessful, the
instruction address becomes the address which is the target of the branch instruction.  For example, suppose we execute the
following branch instruction,
 
                    BE   THERE
                    CLC  X,Y
                     ...
             THERE  EQU  *
                    MVC  X,Y
 
If the condition code indicates “equal”, the address specified by the label  “THERE” will be placed in the instruction address field of
the PSW.  When the CPU loops back to fetch the “next”  instruction, the “MVC” instruction is retrieved rather than the “CLC”
instruction.
 

http://csc.columbusstate.edu/woolbright/ARCHITEC.HTM[9/21/2011 4:21:48 PM]


storage to storage type one
Contents

 
 
   Character data is created by specifying a “C” for the type in a DC or DS declarative.  In this format, each character occupies 1
byte of storage.  Characters are represented using the EBCDIC encoding sequence where each character is presented using 8
bits.  As a result, there are 2 8 = 256 possible bit patterns or characters which can be formed.
 
   A character field can be created using either of the following formats,
           
                      name           DC      dCLn’constant’
        or
                      name           DS      dCLn
 
where ‘name’ is an optional field name
          ‘d’ is a duplication factor used to create consecutive copies of the field (default = 1 copy)
          ‘C’ represents the character data type
          ‘L’ represents an optional length (default = 1 byte)
          ‘n’ is the number of bytes in the field
          ‘constant’ is an initial value of the field in character format.
 
   It is important to note that if a name for a field is specified, it will represent the address of the first byte of the field.  Additionally,
the name of the field will be associated with a length attribute which equals the number of bytes in the field.  If the “Ln”
construction is omitted in a DS, the length will default to 1 byte. If the “Ln” construction is omitted in a DC, the length of the
constant determines the field length. The length of a field defined using DC is limited to a maximum of 256 bytes and the length of
a field defined using DS is 65,535 bytes.
 
   When specifying a constant, the length of the constant and the length of the field may differ in size.  If the length of the constant
is shorter than the field length, the assembler will pad the constant on the right with blanks to fill up the field.  If the constant is
longer than the field, the constant will be truncated on the right so that it will fit inside the field.  The assembler does not generate
a warning message when this occurs.
 
   During assembly, fields that were defined consecutively in the source code with DC’s or DS’s, are assigned consecutive storage
locations in the program according to the value of the location counter which is maintained by the assembler.  For example, in the
fields below, if FIELDA is associated with address x’1000’, then FIELDB is located at x’1003’ and FIELDC is located at x’100C’.
  
                   LOCATION
 
            1000     FIELDA   DS   CL3
            1003     FIELDB   DS   CL9
            100C     FIELDC   DS   CL3
  
An exception to sequential allocation of fields occurs if the duplication factor is specified as 0.  In this case the location counter is
not advanced and the next field redefines the previous field.  Consider the following example and note the location counter values.
 
 
 
               LOCATION
 
         1000     FIELDA   DS   0CL5
         1000     FIELDB   DC    CL2’AB’
         1006     FIELDC   DC    CL3’CDE’
  
   In this case, FIELDB and FIELDC are allocated addresses “inside” FIELDA.

http://csc.columbusstate.edu/woolbright/CHARDATA.HTM[9/21/2011 4:21:49 PM]


storage to storage type one
Contents

          Some Typical DS’s and DC’s:


 
   A        DS    CL8      An 8-byte character field
   B        DS    C        A 1 byte character field    
   C        DS    CL2000   A 2000 byte field
   NAME     DS   0CL20     A field that is subdivided
   LNAME    DS    CL10     The first subfield
   FNAME    DS    CL10     The second subfield
   BLANK1   DC    CL80’ ’  A blank 80-byte field, L’BLANK1 = 80
   BLANK2   DC  80C’ ’     80 consecutive 1-byte fields, L’BLANK2 = 1
   D        DC    CL2’ABC’ Constant too long - right truncation, D= ’AB’
   E        DC    CL5’AB’  Constant too short - padded, E = ’AB   ’     
   F        DC   3C’XY’    L’F = 2, 3 fields created (XYXYXY), F = ’XY’
            DC    C’COST’  An unnamed, initialized field
  
      Note - L’ indicates the length attribute of the following field.

 
1.  A common coding error that occurs when defining a field with a constant, is to choose DS instead of DC.   Consider the
following example,
 
                   LNAME  DS    CL10’SMITH’
 
On first glance, the code appears correct, and in fact, it is syntactically correct.  The assembler will not complain about the
construction.  But the constant is treated as a comment and the field remains uninitialized.     
 
2.  Pay careful attention to the constants you provide.  If the constant is too long, it will be truncated.  If it is too short, it will be
padded with blanks.
 
 
3. Learn to recognize a working subset of characters and their hexadecimal equivalents.  The list below ,consisting of the alphabet,
a blank, the digits, and some punctuation symbols, is a good start.
 
                      Character         Hex Equivalent         Character         Hex Equivalent
 
             A             C1             0             F0
             B             C2             1             F1
             C             C3             2             F2
             D             C4             3             F3
             E             C5             4             F4
             F             C6             5             F5       
             G             C7             6             F6
             H             C8             7             F7
             I             C9             8             F8
             J             D1             9             F9
             K             D2             BLANK         40
             L             D3             ,(COMMA)      6B

http://csc.columbusstate.edu/woolbright/CHARDATA.HTM[9/21/2011 4:21:49 PM]


storage to storage type one
Contents
             M             D4             . (PERIOD)    4B
             N             D5             * (ASTERISK)  5C
             O             D6
             P             D7
             Q             D8 
             R             D9
             S             E2
             T             E3
             U             E4            
             V             E5
             W             E6
             X             E7
             Y             E8
             Z             E9    

http://csc.columbusstate.edu/woolbright/CHARDATA.HTM[9/21/2011 4:21:49 PM]


packed data
Contents

 
  
   Packed decimal data fields are created by specifying a “P” for the type in a DC or DS declarative.  In this format, when
assembled, each byte in the field contains 2 decimal digits except the right-most byte in the field which contains a decimal digit
followed by a sign.  The valid positive signs are the hexadecimal characters A, C, E, and F.  The valid negative signs are the
hexadecimal characters B and D.  The “preferred” signs, those which are generated by the machine or chosen by the assembler,
are positive “C” and negative “D”. It is standard practice to use “C” and “D”, but be aware that the other signs are recognized as
well.  Consider the two fields defined below,
 
                    AMOUNT1      DC    PL3’+20’    
                    AMOUNT2      DC    PL2’-34’
 
   In the first example the assembler generates  x’00020C’ for AMOUNT1 and  x’034D’ for AMOUNT2. 
 
   A packed decimal field can be created using either of the following formats,
           
                      name           DC      dPLn’constant’
        or
                      name           DS      dPLn
 
where ‘name’ is an optional field name
          ‘d’ is a duplication factor used to create consecutive copies of the field (default = 1copy)
          ‘P’ represents the packed decimal data type
          ‘L’ represents an optional length (default = 1 byte)
          ‘n’ is the number of bytes in the field
          ‘constant’ is the initial value of the field in decimal format.  Optionally, a decimal
                          point and a + or - sign can be coded but the decimal point is not assembled.
 
   It is important to note that if a name for a field is specified, it will represent the address of the first byte of the field.  Additionally,
the name of the field will be associated with a length attribute which equals the number of bytes in the field.  If the “Ln”
construction is omitted in a DC, the length will be just large enough to accommodate the digits specified in the constant (along with
a padded 0 on the left if the number of digits in the constant is even).  In a DS declarative, “Ln” must be coded.  The length of a
packed field defined using a DC or DS is limited to a maximum of 16 bytes.  This limits the size of decimal fields to 31 digits.
 
      During assembly, fields that were defined consecutively in the source with DC’s or DS’s are assigned consecutive storage
locations in the program according to the value of the location counter which is maintained by the assembler.  For example, in the
fields below, if PKD1 is associated with address x’1000’, then PKD2 is located at x’1008’ and PKD3 is located at x’1011’.
  
     LOCATION
 
         1000       PKD1     DS    PL8
         1008       PKD2     DC    PL9’20’
         1011       PKD3     DS    PL3

            Some Typical DS’s and DC’s:


 
   R        DS    PL8    An 8-byte field reserved for packed data
   S        DS    PL16   The maximum size of a packed field (31 digits)
   T        DS    PL1    The minimum size of a packed field (1 digit)
   U        DS   3PL4    Three consecutive packed fields (U refers to
                         the first field)
   V        DC    P’123’    V = x’123C’, field is assumed positive
   W        DC    P’-123’   W = x’123D’
   X        DC    P’12’     X = x’012C’, field padded with a 0 to fill
                            up 2 bytes
   Y        DC    PL4’12’   Y = x’0000012C’, constant shorter than the

http://csc.columbusstate.edu/woolbright/PACKDATA.HTM[9/21/2011 4:21:50 PM]


packed data
Contents
                            field length - padded
   Z        DC    PL2’12345’   Z = x’345C’, constant too big, truncation
                               occurs on the left  
   DOG      DC    P’123.45’  DOG = x’12345C’, decimal is treated as a
                             comment, not assembled
 

 
1.  Be sure and use DC instead of DS when providing a constant.  Consider the example below,
 
                   AMOUNT     DS     PL4’1234’
  
    The assembler will not complain about you providing a constant on a DS statement.  It will, however, ignore the constant and
treat it as a comment.   The field remains uninitialized.
 
2.      Be sure to make any packed fields you define large enough to hold any possible values that might be developed in them.  You
cannot err by overestimating the size of a packed field.  On the other hand, it is disastrous to underestimate the size of a
packed field - this will result in truncation of digits in arithmetic operations (decimal overflow exception). 
 
3.      The specification of “P” as the type of data does not insure that the data is packed.  In fact,
      many kinds of data might be stored in a packed field.

http://csc.columbusstate.edu/woolbright/PACKDATA.HTM[9/21/2011 4:21:50 PM]


binary data
Contents

 
   Fixed point data fields, more commonly called “Binary” data fields, are defined using an “F” or an “H” in a DS or DC declarative. 
The “F” creates a fullword (4-byte) field containing a binary integer in 2’s complement format.  In this format, the integer can be
positive or negative.  The “H” designator is used to create halfword (2-byte) fields containing 2’s complement signed integers.  In
both formats, the length indicator “Ln” is usually omitted since the length is understood to be 2 or 4.  When the length indicators
are absent, the fields will be aligned on either halfword or fullword boundaries.  (A halfword boundary is an address that is evenly
divisible by 2, while fullword boundaries are evenly divisible by 4.)  In order to align a field properly, the assembler may generate
from 1 to 3 unused bytes called “slack” bytes.  Consider the example below.  We assume that field “X” is located at address
x’1000’ and that the addresses of the bytes are shown inside each byte.   
 
                       LOCATION
 
             1000        X         DS    CL1
             1004        Y         DS    F
 

                   
 
 
   It is possible to code a length for fullword and halfword binary fields.  Specifically, we may code “FL4” and “HL2”.  When a length
is indicated, slack bytes will not be generated.  Consider the following example which is similar to the example above, but
generates no slack bytes.
 
                       LOCATION
 
             1000        X         DS    CL1
             1004        Y         DS    FL4
 
                   

                   
 
 
 
   Fullword and halfword alignment can also be obtained with another technique:  Coding a 0 duplication factor forces proper
alignment for the succeeding field.  For instance, the following example forces FIELDA to be fullword aligned.
 
                                                      DS   0F
                 FIELDA   DS   ...
 

          Some Typical DS’s and DC’s:

http://csc.columbusstate.edu/woolbright/BINDATA.HTM[9/21/2011 4:21:51 PM]


binary data
Contents
 
   J         DS    F     A fullword field, properly aligned
   K         DS    H     A halfword field, properly aligned
   L         DS    FL4   A fullword field, no slack bytes generated
   M         DS    HL2   A halfword field, no slack bytes generated
   N         DC    F’2147483647’   Maximum size of a binary fullword =
                                   231 - 1
   O         DC    H’32767’        Maximum size of a binary halfword =
                                   215 - 1
   P         DC    F’-2147483648’  Minimum size of a binary fullword =
                                   -231 - 1
   Q         DC    H’-32768’       Minimum size of a binary halfword =
                                   -215 - 1
   R         DC    F’0’      A fullword containing a zero
   S         DC    H’40000’  Error - constant too large
             DS   0F         Provide fullword alignment for the
                             subsequent field
             DS   0H         Provide halfword alignment for the
                             subsequent field
   T         DC    H’20’     T = x’0014’
   U         DC    F’-20’    U = x’FFFFFFEC’  - 2’s complement integer
   V         DC    H’92’     V = x’005C’                

1.  Remember that halfword fields are fairly small - between 32767 and -32768.  Don’t select a halfword if you think your results
may exceed these values.
 
2.  When defining fields in an input or output buffer, fullword and halfword fields are not usually aligned in order to conserve space
on a file.  Remember to code the length indicator in these cases.
 
 

http://csc.columbusstate.edu/woolbright/BINDATA.HTM[9/21/2011 4:21:51 PM]


DC
Contents

 
   Define Constant (DC) is used to create and initialize fields at assembly time.  The word “constant” in the title is something of a
misnomer since fields created with DC are initialized with their assembled values when the program is loaded, but are subject to
modification when the program begins execution.  This declarative has the following format,
 
                    name       DC      dTLn’constant’   
 
where ‘name’ is the optional field name,
          ‘d’ is a duplication factor which allows you to create consecutive copies of the field -
              a 0 duplication factor leaves the location counter unchanged,
          ‘T’ is a data type -   C  -  Character
                                        Z  -   Zoned Decimal
                                        P  -   Packed Decimal
                                        H  -   Binary Halfword
                                        F  -   Binary Fullword
                                        A  -   Address
                                        V  -   Virtual Address
                                        X  -    Hexadecimal
                                        B  -    Binary,
           ‘L’ stands for length,
           ‘n’ is the number of bytes in the field length,
           ‘constant’  is an appropriate constant of the specified type contained in apostrophes.
 

         The following are some sample DC’s.  For more information about a particular data type, consult the data type
documentation.
 
                                    FIELD DEFINITION                   HEXADECIMAL CONTENTS
 
             A         DC      C’ABC’           C1C2C3
             B         DC      CL4’ ’           40404040
             C         DC      CL4’A’           C1404040
             D         DC     2C’AB’            C1C2C1C2
             E         DC      X’12AB’          12AB
             F         DC      P’12345          12345C
             G         DC      H’25’            0019
             H         DC      F’-3’            FFFFFFFD
             I         DC      CL3      Assembly Error - No constant
                       DC      CL30’ ’  Field name is not required
             J         DC     0CL5      0 Duplication factor
             K         DC      CL3      J And K have the same address
             L         DC      CL2      J Contains K and L 
 
 
 
 
 

http://csc.columbusstate.edu/woolbright/DC.HTM[9/21/2011 4:21:52 PM]


data conversions
Contents

 
    Programmers often find it necessary to change data from one data type to another.  We will call this process “data conversion”. 
There are a number of instructions devoted to data conversion that we will examine; specifically, we will discuss conversion
instructions involving four important data types:  Zoned Decimal, Character, Packed Decimal, and Binary data types.  The following
diagram illustrates all possible conversions among the 4 data types, and the instructions necessary to perform the conversions.
 

 
Converting from Zoned and Character to Packed
 
   Zoned decimal data and character data that contains digits have closely related data formats.       ( See Zoned Decimal Data
and Character Data.) For example, consider the definitions below.
 
               CFIELD    DC   C’12345’    CFIELD = X’F1F2F3F4F5’
               ZFIELD    DC   Z’12345’    ZFIELD = X’F1F2F3F4C5’
 
In fact, the only difference above occurs in the zone portion of the rightmost byte.  The zoned field contains a “C” while the
character field contains an “F”.  In a zoned format both “C” and “F” represent a positive sign (+) and so CFIELD AND ZFIELD are
equivalent as zoned decimal fields.  As a result, the PACK instruction can be used to convert both of these fields to a packed
format:
 
 
 
         CPACKED   DS     PL3
         ZPACKED   DS     PL4
         DBLWD     DS     D
                   ...
                   PACK   CPACKED,CFIELD    CPACKED = X’12345F’
                   PACK   ZPACKED,ZFIELD    ZPACKED = X’0012345C’
                   PACK   DBLWD,CFIELD      DBLWD =  X’000000000012345F’
 
In converting the character field to packed decimal in the first example above, we decided to use a 3 byte field to hold the result. 
This decision is somewhat arbitrary.  Since the character field contained 5 digits, it takes at least 3 bytes to hold the result in a
packed format ( 2 packed digits per byte plus the sign).  A smaller choice would have caused truncation of digits on the left.  A

http://csc.columbusstate.edu/woolbright/CONVERT.HTM[9/21/2011 4:21:53 PM]


data conversions
Contents
larger field could have been chosen which would have resulted in the field being padded with zeros on the left.  This in fact,
happened when we packed the zoned field into a 4 byte field and again when we packed into a doubleword.  There is a good
reason we might want to pack a field into a doubleword and that is if our goal is to ultimately convert to binary format.  This is
discussed in the next topic.
 
Converting from Packed Decimal to Binary
 
   In converting to Binary with the CVB instruction, there is a requirement that the packed field be a properly aligned doubleword. 
The range of integers which can be successfully converted is      -2,147,483,648 to 2,147,483,647.  Many programmers will use a
work area for this purpose and PACK or ZAP the doubleword with the required field before converting to binary in a register:
 
                        ZAP   DBLWD,PFIELD  TRANSFER FIELD TO DBLWD
                        CVB   R6,DBLWD      BINARY VERSION TO R6
                        ...
              PFIELD    DC    P’2345’
              DBLWD     DS    D     DOUBLEWORD WORK AREA
 
In the example above “PFIELD” contains a packed decimal value and we wish to convert this value to 2’s complement binary in a
register.  First the field is moved to a double word “staging” area called “DBLWD”.  Since PFIELD is packed, the field is transferred
to DBLWD with a ZAP rather than a MVC.  The CVB instruction performs the conversion from packed to binary.
 
Converting from Binary to Packed Decimal
 
   The requirements for converting from binary to packed decimal using the CVD instruction are similar to those for using CVB.  In
this case, the field that is to receive the packed decimal field must be a doubleword.  Since a doubleword can hold up to 15 packed
digits, any value in a register can be converted to packed decimal.  A small problem arises after the conversion if we wish to edit
the data into a printable format.  Since the doubleword will contain 15 digits, editing the result can be a bit cumbersome.  A
common practice is to ZAP the double word into a smaller packed field that could hold the result before proceeding to edit the data:
 
                        CVD    R6,DBLWD         CHANGE TO DECIMAL
                        ZAP    SMALLPK,DBLWD    DBLWD FIELD IS TOO LARGE
                        ...
              DBLWD     DS     D
              SMALLPK   DS     PL4             
 
The size of the smaller packed field is somewhat arbitrary.  It must be big enough to hold the maximum integer you might process. 
Know your data!
 
 
Converting from Packed Decimal to Character
 
   Preparing a packed field for printing involves the creation of an appropriate edit word and the use of the ED or EDMK
instruction.  This is an error-prone process for many beginning assembler programmers and many headaches could be avoided by
paying attention to a few details:
 
   1)  Start with the packed field and count the number of packed digits it contains.
 
   2)  Create an edit word for the packed field.  Count the number of X’20’s and X’21’s that appear
        in the edit word.  The count in step 2 must equal the count in step 1.  If you make a
        mistake with this, the results are highly unpredictable!
 
   3)  Count the number of bytes in the edit word.  Count every byte including the fill character. 
        Now create an output field that is exactly the size of the edit word.  Again, a mistake here is
        fatal.
 
  4)  At execution time, move the edit word to the output field and edit the data.
 
   For example, assume we want to edit the packed field below into a dollars and cents format.
 
               PKFIELD   DC    PL4’543210’   PKFIELD = X’0543210C’
 
   Examining PKFIELD we see that it contains 7 packed digits.  This means that the edit word we create must contain 7 X’20’s or
X’21’s.  The following edit word will work.
 

http://csc.columbusstate.edu/woolbright/CONVERT.HTM[9/21/2011 4:21:53 PM]


data conversions
Contents
               EDWD      DC    X’4020206B2020214B2020’
 
Counting the bytes in EDWD we see it contains 10.  Next we create an output field capable of containing the edit word.
 
               POUT      DS    CL10
 
Now we are ready to edit the data.
 
               MVC       PKOUT,EDWD
               ED        POUT,PKFIELD  
 
The hexadecimal contents of PKOUT after executing the code above is X’4040F5F46BF3F24BF1F0’  and would appear in a
printed report as ‘  5,432.10’.
 
Converting from Packed Decimal to Zoned Decimal
 
   The conversion to zoned from packed is a simple and straightforward use of the UNPK instruction.  Be sure to provide a field big
enough to hold the result.  Consider the following conversion.
 
                          UNPK  ZFIELD,PKFIELD
                          ...
                PKFIELD   DC    P’112233’ PKFIELD = X’0112233C’
                ZFIELD    DS    ZL7
 
After execution, ZFIELD contains X’F0F1F1F2F2F3C3’.
 
 
 
A COMPLETE EXAMPLE
 
   The following code demonstrates how a single zoned decimal field (ZFIELD) can be converted to the other three data types. 
 
           PACK      PKFIELD,ZFIELD     NOW WE HAVE A PACKED VERSION
           ZAP       DBLWD,PKFIELD      PREPARE TO CONVERT TO ...
           CVB       R8,DBLWD           ...A BINARY VERSION IN R8
           MVC       CHOUT,EDWD         GET READY TO EDIT...
           ED        CHOUT,PKFIELD      ... A CHARACTER VERSION IN CHOUT
           UNPK      ZOUT,PKFIELD       BACK TO A ZONED VERSION IN ZOUT
           ...
  DBLWD    DS        D
  ZFIELD   DS        ZL5      5 ZONED DIGITS
  PKFIELD  DS        PL3      3 BYTES WILL HOLD ZFIELD’S DATA
  EDWD     DC        X’402020202120’  6 BYTE EDIT WORD
  CHOUT    DS        CL6
  ZOUT     DS        ZL5     
  

http://csc.columbusstate.edu/woolbright/CONVERT.HTM[9/21/2011 4:21:53 PM]


storage to storage type one
Contents

 
   We use the term “simple” to refer to an assembler program that is organized using a single control section.  Programs that involve
multiple control sections are the topic of another article.  Every program can be divided into two parts:
 
An executable section that consists of all the instructions in the program which direct the action of the central processing unit. 
This includes all the instructions in the instruction set. Some examples are MVC, AP, and CR.  These instructions move data,
perform arithmetic, and compare fields.  Also included in the executable section are executable macros like GET, PUT, OPEN and
CLOSE.  These macros generate executable instructions from the instruction set.
 
A non-executable section that consists of all the “directive” statements in the program that control how the assembler processes
the source code.  These include the DS and DC directives (used to create variables and storage areas), EQU directives (used for
register names and target labels), the LTORG directive (used to create a literal pool), USING and DROP directives (used to control
register selection by the assembler), and a several “cosmetic” directives like PRINT, EJECT and SPACE.
 
   Physically, the executable section and the non-executable section are intermixed.  If you think of the executable section being
colored “red”, and the non-executable section being colored “blue”, then from afar, our “simple program” will appear as a red block
on top of a blue block.  A closer look will reveal that the red block contains a few scattered lines of blue code.  This organization is
indicated in the diagram below. 
 

 
 
The Executable Section
 
   Next we consider the organization of the executable section.  There are several things that must occur upon entry into every
program.  We will collectively refer to these tasks as the “standard entry section”.  These tasks are several:
 
1)  Copy the current contents of the registers into a save area which is located in the non-executable part of the program,
 
2)  Establish addressability (the ability to use symbols),
 
3)  Prepare the program for calling other programs.
 
   After the standard entry section the programmer is free to write the code that comprises the body of the program.  This section
instructs the central processing unit to perform the tasks for which the program is being written.
 
   Finally, coding the “standard exit section” completes the executable section.  There are three tasks in this section:
 
1)  Restore the registers to their original state upon entering the program,
 
2)  Set a return code which will be used by the calling program or operating system,
 
3)  Branch back to the calling program or operating system.

http://csc.columbusstate.edu/woolbright/Simple.HTM[9/21/2011 4:21:54 PM]


storage to storage type one
Contents
 
   A thorough description of the standard entry and exit sections can be found in Program Linkage.
 
   Scattered throughout the executable section you will see the following types of non-executable statements:
 
1)  The CSECT directive that delimits the beginning of the control section,
 
2)  Cosmetic directives like PRINT, EJECT, and SPACE which are used to control the appearance of the assembler listing of the
source code,
 
3)  Comments,
 
4)  EQU directives which are used to create symbols and labels, and
 
5)  USING and DROP directives that control the registers selected by the assembler when creating base/displacement addresses.
 
The Non-Executable Section
 
   The non-executable section follows the executable section.  While the programmer has wide latitude in organizing any assembler
program, we will outline a typical layout of a “simple” program’s non-executable section.  The typical organization would include the
following items in order:
 
1)  DCB’s (data control blocks) that define the files that will be processed by the program,
 
2)  DS and DC directives for creating variables and storage areas used by the executable instructions,
 
3)  The LTORG directive which indicates the position of the literal pool in the program,
 
4)  The END directive which delimits the physical end of the program, and
 
5)  Comments which may be scattered throughout the non-executable section.

http://csc.columbusstate.edu/woolbright/Simple.HTM[9/21/2011 4:21:54 PM]


qsam files
Contents

 
    The term “sequential file” refers to the manner in which the records of a file will be processed, and to a lesser extent, the way in
which the file records are physically organized on some media.  For input, a sequential file is usually read starting from the first
record, proceeding to the second record, then the third, and continuing in this fashion to the end.  For sequential output files, we
will write out the first record, then the second, then the third, proceeding in this manner to the last record.  The most commonly
used sequential file for IBM mainframes is a QSAM file.  QSAM is an acronym for “queued sequential access method”.  In this
topic we investigate how QSAM files are created and processed.  We will also learn about record blocking as well as “locate” and
“move mode” input and output.
 
Defining a QSAM File (Queued Sequential Access Method)
 
   QSAM files are defined inside a program using IBM’s DCB macro.  This macro generates a  block of storage called a “data
control block” which contains information that is used by the operating system when processing the file that the macro defines. The
macro is non-executable, and serves only to generate a control block at assembly time.  Being non-executable, the macro is coded
in the program at a point which would not become part of the execution sequence.  Many programmers choose to code the DCB
just after the executable portion of the program, and before the declarations for variables.  This is a fairly safe location and serves
to keep the DCB’s from becoming corrupted by the program accidentally.  At run time, the information in the DCB is combined with
information in the job control language data definition statement (DD), as well as information in the data set label in order to
complete the information that is stored in the DCB.  The data set label is a control block that is created and stored with the file
when it is created.  Later we will investigate how the information from the DCB, the DD statement, and the data set label are
combined at run time.
 
   Lets first look at a sample DCB macro as it might appear in a program.
 
                 CUSTFILE DCB  DDNAME=CUSTOMER,                    +
                               DSORG=PS,                           +
                               LRECL=80,                           +
                               MACRF=(GM),                         +
                               RECFM=FB,                           +
                               EODAD=ENDFILE            
 
By coding a DCB, we are defining a file and its characteristics.  In the DCB above, the file’s internal name, the name that will be
used inside the program, is “CUSTFILE”.  Whenever the program references the file, this is the name that will be used.  For
instance, to read a record in the file we might code “GET  CUSTFILE,MYREC”.  The internal name appears in the first 8 columns
of the macro.  This is followed by the macro name, “DCB”.  The rest of the macro is a sequence of keyword parameters which may
be coded in any order:
 
1)  DDNAME -  This parameter assigns the file a “second” name which appears in the DD statement in the JCL that is used to
execute the program.  The following is typical of the DD statement that would be part of the JCL.
 
            //CUSTOMER  DD  DSN=TSYSAD2.PRIVATE.DATA,DISP=SHR
 
Notice that the word “CUSTOMER”, which we will call the “JCL name”,  appears in the name field of the DD statement and is used
to associate the JCL name with a “physical file name”.  The physical file name is the actual file name as it might appear in the
system catalog.  As a result, we have three names for the file we are processing:  an internal name, a JCL name, and a physical
file name.  The purpose for having three names is to provide some “indirection” in the file names so that our program is not tied to
a single physical file.  By changing the DD statement we can change the physical file that the program references.  This is
illustrated below. 
 
       //CUSTOMER  DD   DSN=TSYSAD2.PRIVATE.DATA1
       //CUSTOMER  DD   DSN=TSYSAD2.PRIVATE.DATA2
 

http://csc.columbusstate.edu/woolbright/QSAM.HTM[9/21/2011 4:21:55 PM]


qsam files
Contents

 
Only one of the DD statements above would appear in the JCL.  If the first was coded, the connections in the upper path would be
indicated.  If the second DD was coded, the connections in the lower path would be indicated.  As you can see from the diagram,
changing the JCL DD statement allows the program to easily process different physical files.
 
2)  DSORG -  This keyword parameter stands for “data set organization” and is used to control the basic structure of the file.  In
this case, PS means “physical sequential” and serves to identify the file as a QSAM file.  The records in the file are stored and
processed sequentially.  Records which are “logically”  in sequence are also physically stored in sequence on the disk.
 
3)  LRECL -  The “logical record length” is the number of bytes in the record structure defined by the programmer and processed
by the program. 
 
4)  MACRF -  This parameter determines the format for the I/O macros that will be used to process the file and the mode in which
the I/O will occur.  For QSAM files there are four possible values that can be coded:  GM, PM, GL, PL.  The “G” in the parameter
value means that the GET macro will be used for accessing the file.  This implies the file is an input file and already exists.  The
“P” means the PUT macro will be used to process the file.  In this case the file is an output file.  The second letter indicates the
mode in which the I/O will occur.  “L” means locate mode I/O and “M” means move mode I/O.  These two modes will be discussed
later in this topic.
 
5)  RECFM -  The RECFM parameter determines whether the logical records the program processes are fixed in length (F), or of
variable lengths (V).  This parameter also controls whether the records are blocked (B) or unblocked.  Here are the typical values
for this parameter and their meanings.
                                    RECFM = F        Fixed size records, unblocked
                                    RECFM = FB      Fixed size records, blocked
                                    RECFM = V        Variable size records, unblocked
                                    RECFM = VB      Variable size records, blocked
 
The concept of record blocking will be discussed later in this topic.
 
6)  EODAD -  The “End of Data” parameter is only coded for input files (MACRF=GM or GL).  This parameter provides a label to
which the program will automatically branch when the “end of file” condition occurs.  The operating system detects the “end of file”
condition while executing a GET macro when there are no records in the file left to be read.  Upon detecting “end of file”, the
operating system transfers control to address coded on the EODAD parameter.
 
Opening a QSAM File
  
   Before you can process any records in a file, the file must be “opened”.  The open process causes the “empty” fields in the DCB
to be filIed in so the file can be processed correctly.  It is
helpful to understand how information in the DCB is constructed.  This process is illustrated in the diagram below.  Some of the
parameters are impractical but serve to illustrate how the information is combined.

http://csc.columbusstate.edu/woolbright/QSAM.HTM[9/21/2011 4:21:55 PM]


qsam files
Contents

 
At assembly time, the DCB is created and initialized with information contained in the program’s DCB macro.  When the job is
submitted for execution, the JCL is initially scanned by the Job Scheduler, and a Job File Control Block (JFCB) is created  first
using the information found in the DSCB if the file already exists, and then overwritten with any parameters found in the DD
statement.  The file is opened at run time, and any information that is missing in the DCB  is supplied by the information in the
JFCB.  Because of the order in which the information is combined from the DCB macro, the DD statement, and the DSCB, the
most important information is that which is placed in the DCB as a result of the parameters coded in the program’s DCB macro. 
This information is supplemented by information gleaned from the DD statement in the JCL.  The only information that is taken from
the DD statement and stored in the DCB, are those fields which were not supplied in the program DCB.  In other words, if a
parameter is supplied in the DCB and on the DD statement in the JCL, only the DCB parameter is used.  Finally, the only
information that is gathered from the data set label is that which was not found in the DCB macro nor in the DD statement.
 
   The OPEN macro has the following format,
 
                  OPEN   (dcb-address,(processing option))
 
          dcb-address -  The label in the name field of the DCB macro.
 
          processing option - 
  
              INPUT -      An existing data set is to be used for retrieving records.
              OUTPUT -  A new data set is being created or the records in an existing file will be
                                replaced by the records that will be written by the program.
              EXTEND -  Records will be added to the end of an existing file.
              UPDAT  -   An existing data set is to be used for retrieving records.  Additionally,
                                existing records can be modified.
 
For example, the following statement opens the file called “CUSTFILE” for input processing.

http://csc.columbusstate.edu/woolbright/QSAM.HTM[9/21/2011 4:21:55 PM]


qsam files
Contents
 
                  OPEN  (CUSTFILE,(INPUT))
 
CLOSING A QSAM FILE
 
   After a file has been processed, it should be “closed”.  This process logically disconnects the program from the file.  During the
close processing, the program DCB is reconfigured with the parameters it initially contained at assembly time.  This means the file
can be opened again for further processing.
 
   The format of the CLOSE statement follows below,
 
                  CLOSE  (dcb-address-1,dcb-address-2,...)
 
          dcb-address-n -  The label in the name field of the DCB macro.
 
The two statements below are examples of how the CLOSE statement can be coded.
 
                  CLOSE  (CUSTFILE)
                  CLOSE  (CUSTFILE,MASTFILE)
 
In the first CLOSE statement, the CUSTFILE is closed while the second CLOSE statement closes two files with one statement.
 
 
 
 
 
 
Record Queuing 
 
   The “Q” in QSAM stands for the term “queued”, and refers to the queuing of records that occurs during input and output
processing.  On the input side, records are brought from an external source (disk, tape,...) into the main memory of the machine. 
The records are delivered into storage areas called “system buffers” where they reside until they are retrieved by the program using
a GET macro.  The queuing process begins when the file is opened with records being delivered to the system buffers even before
the first GET is executed.  During execution of the program the operating system tries to keep the system buffers full of records so
that the program will not have to wait for a record to be retrieved from the external device.  This has the effect of speeding
program execution.
 
   During output processing, records that are produced by the program using the PUT macro are also placed into system buffers
where they reside until the operating system can retrieve them and transfer them to an external storage device.  By “buffering” the
output, the program can continue execution without waiting on the external device.
 
   Input and Output queuing is illustrated in the diagram below.
 

 
   As depicted above, the diagram illustrates “move mode” input and output.  The term “move mode” refers to the process of
moving a record from a system input buffer to a program input area or from a program output area to a system output buffer. 
These moves occur as a result of coding GET and PUT.
 
Reading and Writing QSAM Records in Move Mode
 

http://csc.columbusstate.edu/woolbright/QSAM.HTM[9/21/2011 4:21:55 PM]


qsam files
Contents
   After a file has been opened for input, the records are available for retrieval.  To read a record you must code a GET macro. 
There are two formats for this macro depending on how the MACRF parameter is coded in the file’s DCB macro.  Coding
“MACRF=GM” determines that records will be retrieved in “move mode”.  This means that when a record is read, a copy of it will
be delivered to a storage area defined by the programmer in the program.  This storage area is called a “buffer” and is designed to
reflect the contents of the record.  Here is an example.
 
                  GET   CUSTFILE,CUSTREC
                  ...
         CUSTREC  DS    0CL80
         CUSTNAME DS     CL40
         CUSTINF1 DS     CL20
         CUSTINF2 DS     CL20
 
The GET macro above names the file as its first parameter and the program buffer area as its second parameter.  Since we are
assuming move mode input, a record is delivered from a system buffer to the storage area called CUSTREC.
   For output processing, the PUT macro is used for writing records to a file.  The MACRF parameter determines the mode in
which records will be processed with MACRF=(PM) indicating move mode input and output.  An example  PUT macro is listed
below.
 
                  PUT   MASTFILE,MASTREC
                  ...
         MASTREC  DS   0CL100
         MASTID   DS    CL8
                  ...
 
First the record that is to be recorded on the file is created in a program area called MASTREC.  All the fields of the record would
be initialized with appropriate values.  When the record has been constructed, it is written to the file by executing the PUT macro. 
The first parameter in the macro is the DCB name of the output file.  The second parameter is the buffer containing the record. 
Execution of the macro causes the information in MASTREC to be transferred to a system buffer where it will be processed at a
later time.
 
Reading and Writing Records in Locate Mode
 
   When MACRF=(GL) is coded, input processing will occur in “locate mode”.  Processing in this mode is more efficient than in
move mode since the records we read are never transferred directly to the program’s storage area, but instead are left in the
system buffers. For files with large numbers of records, or large record sizes, the processing time that is saved by using locate
mode rather than move mode, can be substantial.  If the records are not transferred directly to a program buffer, how can the
program access the information in a record?  The answer is that the programmer must use a DSECT to reference the storage.
(See DSECTS.)  The GET macro takes an alternate form for locate mode processing.  In this format, the macro has a single
parameter which is the file DCB name.  A sample locate mode GET is coded below.
 
                  GET   CUSTFILE
             
After executing the macro, the operating system initializes register one with the address of the record that was delivered as a result
of the GET.  This address will be inside a system buffer.  Providing access is a simple matter of loading the address of the record
into the register which is associated with the DSECT.  This is illustrated below.
 
          CUSTREC DSECT
          CUSTBAL DS    PL4         CUSTOMER BALANCE
                  ...               OTHER DSECT FIELDS
 
                  USING CUSTREC,R5
                  GET   CUSTFILE
                  LR    R5,R1         MAKE R5 POINT AT THE RECORD
                  ZAP   TEMP,CUSTBAL  PROCESS THE FIELDS IN THE RECORD
                  ...
 
After the GET is executed, the address of the delivered record is placed in register one.  Subsequently, the address is loaded into
register 5 by the LR instruction.  The USING statement provides the association between the DSECT name and register 5.  With
register 5 loaded with the appropriate address, addressablility to the record is established with the names in the DSECT.
 
   Locate mode output is indicated by coding MACRF=(PL) in the DCB macro.  To write a record to a file, the PUT macro is
executed first.
 
                  PUT   MASTFILE
Executing the PUT causes the operating system to place the address of an available buffer in register one.  Using the LR

http://csc.columbusstate.edu/woolbright/QSAM.HTM[9/21/2011 4:21:55 PM]


qsam files
Contents
instruction, this address is then copied to a register that controls an output DSECT.  Once addressability has been established to
the output record, the record is created by the program.  The record remains available for further program processing until the next
PUT is issued, or the file is closed.  The following code is typical of locate mode output.
 
               MASTREC   DSECT
               MASTNO    DS     CL5     CUSTOMER NUMBER
               MASTBAL   DS     PL5     CUSTOMER BALANCE
                         ...
                         USING  MASTREC,R6
                         PUT    MASTREC
                         LR     R6,R1    MAKE R6 POINT AT EMPTY REC
                         ZAP    MASTBAL,BALPK   REC FIELDS AVAILABLE
                         ...
 
Keep in mind that register one is a “volatile” register and is subject to change when executing a system macro or calling another
program.  Be sure to make a copy of  register 1 immediately after executing PUT or GET. 
 
Record Blocking and Deblocking
 
   The term blocking refers to the operating system process of combining multiple logical records into larger physical records called
“blocks”.  A logical record is the record structure defined by the programmer and consists of a collection of related fields that
logically belong together.  A physical record is a collection of logical records which have been combined for the purpose of storing
them efficiently on an external device like a disk or tape drive.  Records are blocked because the process of accessing externally
stored data is expensive in terms of cpu time.  For instance, in the time it takes to move a disk arm, hundreds of thousands of
instructions can be executed by the cpu.  For efficiency, rather than returning a single record when a program requests a “read”
operation, the operating system delivers an entire block of records from disk to memory.  The process of separating records from a
block and delivering them individually to a program is called deblocking.
 
   The choice of blocking or not blocking a group of records is made by the programmer when coding the RECFM parameter. 
Choosing RECFM =FB or VB selects the blocked format.  In practice, most files are blocked.  The exception is made for files with
large records containing thousands of bytes.  In the pictures above, the system buffers correspond to blocks from which individual
records are delivered to the program either in move or locate mode.
 
   The programmer can also control the size of the blocks in a file using the BLKSIZE parameter coded in the program’s DCB.  For
example, if the programmer has coded LRECL=80 and BLKSIZE=8000, then each block will contain 100 logical records. 
Computing an optimal block size requires a knowledge of the device on which the data is recorded and is beyond the scope of this
discussion.  For IBM’s ESA operating system, block sizes will be computed automatically if the BLKSIZE parameter is omitted in
the DCB and on the DD statement when the file is created.  
 

http://csc.columbusstate.edu/woolbright/QSAM.HTM[9/21/2011 4:21:55 PM]


loops
Contents

 
   A loop is a control structure which allows a block of instructions, the loop body, to be executed repeatedly in succession.  In
this article we investigate loop control structures and how they are constructed in assembly language.  There are two categories of
loops:
 
1)  Counted Loops -  Loops in which the iteration number, the number of times the loop should be executed, is known before the
loop is entered.
 
2)  Conditional Loops - Loops which will be continually iterated until a prescribed condition occurs.
 
Creating Counted Loops
 
   The most commonly used instruction for creating a counted loop is the Branch On Count instruction, which has mnemonic BCT. 
The iteration number is first loaded into a register which is subsequently manipulated by BCT.  Each time the BCT is executed, the
iteration number in the register is decremented by one.  After the register is decremented, the register is tested.  If the result in the
register is not zero, a branch is taken to the address specified in Operand 2.  If the test reveals that the result in the register is
zero, the loop is terminated and execution continues with the instruction following the BCT.  Here is a sample loop that would be
iterated 10 times.
 
            LA      R5,10             PUT THE ITERATION NO. IN R5
            LOOPTOP EQU   *
 
                    ...LOOP BODY GOES HERE
 
                    BCT   R5,LOOPTOP  DECREMENT R5,IF NOT 0, BRANCH BACK
 
   In the code above, the register that will control the loop is initialized at 10 and then the statements in the loop body are
executed.  At the end of the first iteration, BCT subtracts 1 from register 5, leaving it set to 9.  The register is tested and since it
does not contain zero,  a branch is taken back to LOOPTOP.  The loop body is executed a second time, and again BCT subtracts
1 from register 5, leaving it set at 8.  BCT tests the content of R5, which is now 8 , and not finding it zero, branches back to
LOOPTOP.  This process continues through 10 iterations of the loop body.  On the tenth iteration, BCT decrements the register
and the result becomes zero. Testing R5 reveals it to be zero.  This time the branch is not taken and control returns to the
statement following the branch on count instruction.
 
   There are two other instructions which are occasionally used to implement a counted loop.  The first instruction that we consider
is called “Branch on Index Less Than or Equal”.  The mnemonic for this instruction is BXLE.  When coded it has three operands:
 
1)  Operand 1 is a register containing a count or an address.
 
2)  Operand 2 is typically an even register of an even-odd consecutive pair of registers.  The even register contains a value which
is used to increment or decrement the value in Operand 1.
The odd register, which is not coded in the instruction, contains a limit or address against which Operand 1 is compared.
 
3)  Operand 3 represents an address to which the instruction will branch if the Operand 1 value is less than or equal to the limit in
the odd register.
 
   For example, consider the following instruction.
 
                    BXLE   R3,R4,LOOPTOP
        
The diagram below illustrates the relationships among the registers used by the instruction.
 
 

http://csc.columbusstate.edu/woolbright/LOOPS.HTM[9/21/2011 4:21:56 PM]


loops
Contents

               
 
 
Each time the instruction is executed, the value in the even register, R4,  is added to the value in the Operand 1 register, R3.  If
the result is less than or equal to the value in the odd register, R5, a branch occurs to the address in Operand 3, LOOPTOP.  The
code listed below uses BXLE to implement a loop. 
 
                    SR    R3,R3     PUT 0 IN R3
                    LA    R4,10     PUT INCREMENT INTO EVEN REG
                    LA    R5,100    PUT LIMIT VALUE IN ODD REG
          LOOPTOP   EQU   *
 
                          ...LOOP BODY
 
                          BXLE  R3,R4,LOOPTOP   EXECUTE THE LOOP
 
 
First, the count in R3 is initialized to 0, the increment is set to 10, and the limit is set at 100.  Each time the BXLE is executed, the
increment in R4 is added to the count in R3 and the result is compared to the limit in R5.  If the new count is less than or equal to
the limit, a branch occurs back to LOOPTOP.  The effect of the statement is to execute the loop 11 times.  ( The loop is executed
once on the equal condition.)
 
   BXLE has a companion instruction called “Branch on Index High”.  The mnemonic is BXH and the instruction is similar in
execution to BXLE except the branch occurs on a “high” condition instead of “less than or equal”.  The following code gives an
example of this instruction.
 
                    LA    R3,5      SET THE COUNT TO 5
                    L     R4,=F’-1’ SET THE DECREMENT TO -1
                    SR    R5,R5     SET THE LIMIT VALUE AT 0
          LOOPTOP   EQU   *
 
                          ...LOOP BODY
 
                          BXH  R3,R4,LOOPTOP   EXECUTE THE LOOP
 
                           
In the example above, the count is set at 5, the decrement is -1, and the limit is 0.  Each time the BXH is executed, the decrement
is added to the count, reducing it by 1.  As long as the result is higher than the limit 0, a branch occurs to LOOPTOP.  The effect
is to execute the loop body 5 times.
    
   The main drawback to using BXLE and BXH is that both instructions require 3 registers.  Since registers are usually at a
premium in most programs, loops are often implemented using BCT.
 
   While the instructions discussed above were specifically designed for the construction of loops,  comparisons of any type, as well
as other instructions that set the condition code, can be used to create  “home-made” loop structures.  In the code below we use a
packed decimal instruction in combination with a branch to implement a counted loop.
 
                    ZAP   COUNT,=P’100’    LOOP 100 TIMES
            LOOPTOP EQU   *
 
                    ...LOOP BODY
 
                    SP    COUNT,=P’1’      DECREMENT ON EACH ITERATION
                    BNZ   LOOPTOP          BRANCH IF NOT ZERO
 
 
In this case, we have decided to loop 100 times.  Each time through the loop the count is decremented by 1.  We take advantage
of the fact that SP sets the condition code based on the result of the subtraction.  If the result is not zero, we loop back to
LOOPTOP.
 
Creating Conditional Loops
 

http://csc.columbusstate.edu/woolbright/LOOPS.HTM[9/21/2011 4:21:56 PM]


loops
Contents
   Conditional loops are characterized by the property that we cannot predetermine the number of times the loop will be iterated.  In
other words, the loop will continue to be executed until a prescribed condition occurs.  The condition is tested “by hand” using one
of the compare instructions; CP for packed data, CLC or CLI for character data, and C or CH for binary data.  The following code
implements a conditional loop that continues to be executed until a field, called “FLAG”, is equal to “Y”.
 
           LOOPTOP  EQU   *
 
                    ...LOOP BODY
 
                    CLI   FLAG,C’Y’    IS THE FLAG SET?
                    BNE   LOOPTOP      NO... BRANCH BACK
 
 
When creating loops of this type, the loop body must contain logic that will eventually cause termination of the loop.  Otherwise an
infinite loop results.
 
   One common use of a conditional loop is for processing all the records in a sequential file.  This is illustrated with the code
below.
 
           GETREC   EQU   *
                    GET   MYFILE,MYRECORD     READ A RECORD
 
                    ...PROCESS THE RECORD
 
                    B     GETREC              LOOP BACK FOR NEXT RECORD
           NEXTSTEP EQU   *
 
 
At first glance, the loop above appears to be an “infinite” loop.  In other words, there does not appear to be logic present that would
allow the program to escape the loop body once it is entered.  This problem is resolved when we execute the GET macro and
there are no more records in the file.  At this point, a branch would occur to NEXTSTEP if we have specified EODAD=NEXTSTEP
in the DCB of MYFILE.  The EODAD parameter causes an unconditional branch to the address we specify in the parameter when
“end of file” is detected.  So, in fact, the loop above is conditional, and continues to execute until “end of file” occurs.
 
   Occasionally you may code an infinite loop by mistake.  When this happens, your program will continue to execute the loop until
it has used up the time allocated to the job by the operating system.  At that point, the program will be interrupted with a “322”
abend.

http://csc.columbusstate.edu/woolbright/LOOPS.HTM[9/21/2011 4:21:56 PM]


packed decimal arithmetic
Contents

 
   Packed decimal is a convenient format for doing many arithmetic calculations in assembly language for several reasons:
 
1)  All computations occur in integer arithmetic (no decimals, 5/2 = 2, etc.),
 
2)  Packed decimal fields are easy to read in a storage dump,
 
3)  Computations occur in base 10.
 
The main disadvantage to packed decimal arithmetic is that decimal points are not stored internally.  This means a programmer
must keep up with decimals and make sure they are printed in the correct positions on any report.
 
   In this topic we discuss commonly used packed decimal computations with examples.  Later we will consider arithmetic
operations with decimal points.
 
Copying Packed Decimal Fields
 
   When copying a packed decimal field, be sure to use the Zero and Add Packed instruction, ZAP.  By using ZAP, you are assured
that the target field will be properly initialized.  Many beginners make the mistake of using MVC when copying packed decimal
values.  This can lead to an error which is illustrated in the following example.
 
                    MVC   AFIELD,PKFIELD    AFIELD = X’038CFF’ 
                    ZAP   AFIELD,PKFIELD    AFIELD = X’00038C’
                    ...
            AFIELD  DS    PL3
            PKFIELD DC    PL2’38’    PKFIELD = X’038C’
                    DC    X’FF’
 
We are copying a 2-byte packed field, PKFIELD,  to a 3-byte field, AFIELD.  Since MVC has an SS 1 format, the length of AFIELD
is used to determine that 3 bytes will be “moved” by this instruction.  The effect of this instruction is to copy the 2 bytes in
PKFIELD and the byte which follows PKFIELD as well.  As a result, AFIELD does not contain a packed value.  On the other hand,
the ZAP above first initializes AFIELD with a packed decimal zero just before adding the packed value of PKFIELD.  This produces
the correct packed decimal value X’00038C’.  This type of error with the MVC instruction occurs each time the fields involved have
different sizes.    
 
   Care must be taken even when using a ZAP to copy a packed field.  If the target field is too small to hold the result, high order
truncation of digits can occur, causing an overflow.  Consider the following example involving AFIELD defined above.
 
                    ZAP  AFIELD,=P’123456789’   AFIELD = X’56789C’
 
After executing the instruction above, the high-order digits of the packed decimal literal have been truncated.  This may or may not
cause the program to abend, depending on the decimal-overflow mask.  (See SPM.)  In the case where the program continues
execution, the programmer is not immediately aware that an error has occurred.
 
   One side effect of executing a ZAP is that the condition code is set to indicate how the target field compares to zero.  The
condition code can be tested with the branch on condition instruction using the extended mnemonics.  Here is an example,
 
                    ZAP   FIELD1,FIELD1    SET THE CONDITION CODE
                    BZ    WASZERO          BRANCH IF ZERO
 
Adding Packed Decimal Fields
 
   Next we consider the problem of adding several packed decimal fields.  In doing this we must estimate the size of the sum and
define a packed decimal work field that will contain it.  The first field that will participate in the sum can be ZAPed into the work
field.  All other fields that contribute to the sum will be added using the AP instruction.  The following example computes the sum
of 3 packed decimal fields.

http://csc.columbusstate.edu/woolbright/PKARITH.HTM[9/21/2011 4:21:56 PM]


packed decimal arithmetic
Contents
 
                    ZAP   SUM,FIELD1
                    AP    SUM,FIELD2
                    AP    SUM,FIELD3
                    ...
            FIELD1  DS    PL3
            FIELD2  DS    PL3
            FIELD3  DS    PL3
            SUM     DS    PL7
 
Notice that SUM was uninitialized, but was zeroed out by the ZAP operation prior to the addition of FIELD1.  The size of SUM is
somewhat arbitrary and could vary based on our knowledge of the data.  In the code above we have avoided the cardinal error of
choosing a field that is too small to hold the result - a packed length 7 field will hold the sum of any 3 packed length 3 fields.
 
 
Subtracting Packed Decimal Fields
  
   The comments above about adding packed fields also apply when subtracting them.  Use the SP instruction to perform the
subtraction.  The main error to avoid is not providing a field large enough to hold the final result.  The code below will compute the
difference of FIELDA AND FIELDB.
 
                    ZAP   DIFFER,FIELDA
                    SP    DIFFER,FIELDB
                    ...
            FIELDA  DS    PL3
            FIELDB  DS    PL3
            DIFFER  DS    PL4 
 
The SP instruction is useful for zeroing out a packed decimal field.  Subtracting a field from itself will accomplish this result.
 
                    SP   DIFFER,DIFFER    DIFFER = 0
 
Comparing Packed Decimal Fields
 
   It is often necessary to compare two packed decimal fields and branch based on how the two fields compare to each other.  In
assembly language, packed fields can be compared using the CP instruction.  This has the effect of setting the condition code. 
Branch instructions are then coded in order to test the condition code and branch accordingly.  Consider the following example
which leaves the “larger”  of two packed fields in a field called “BIGGER”.  First FIELDA is copied to BIGGER, then the fields are
compared.  A branch instruction, BNH,  tests the condition code and a branch occurs to the label “THERE” if the condition code is
“Not High”.  In other words, a branch occurs if FIELDB is equal or less than FIELDA.  On the other hand, if FIELDB is larger, the
branch is not taken and execution continues with the ZAP which copies FIELDB over the previous value in BIGGER. 
 
                    ZAP   BIGGER,FIELDA     ASSUME FIELDA >= FIELDB
                    CP    FIELDB,FIELDA     FIELDB > FIELDA?
                    BNH   THERE             BRANCH IF EQUAL OR LOW
                    ZAP   BIGGER,FIELDB     CHANGE TO THE LARGER VALUE
            THERE   EQU   *    
 
   It is a beginner’s mistake to compare packed fields with the CLC instruction.  The compare logical character instruction was not
designed to accommodate packed decimal data.  The following code illustrates some of the problems that can occur.
 
                    CP    AFIELD,BFIELD   CONDITION CODE = EQUAL
                    CLC   AFIELD,BFIELD   CONDITION CODE = HIGH
                    CLC   SHORTNO,LONGNO  CONDITION CODE = HIGH
                    ...
            AFIELD  DC    X’12345C’       AFIELD = +12345
            BFIELD  DC    X’12345A’       AFIELD = +12345
            SHORTNO DC    X’123C’
            LONGNO  DC    X’0000123C’
 
Using CP in the first line, the fields are properly compared as equal packed decimal fields.          ( Remember that C and A are
valid plus signs for packed decimal data.)  The first CLC instruction sets the condition code to “high” when it compares the third
bytes of AFIELD and BFIELD.  As character data, X’5C’ is higher than X’5A’.  The second CLC illustrates another problem with
using CLC.  In this case, the condition code is set to high when comparing the first bytes as character data.  In fact, the fields are
equal when treated as packed decimal fields.
 
Multiplying Packed Decimal Fields
 
   The MP mnemonic is used for multiplying packed decimal fields.  This instruction contains two operands which are multiplied; the

http://csc.columbusstate.edu/woolbright/PKARITH.HTM[9/21/2011 4:21:56 PM]


packed decimal arithmetic
Contents
product is copied to the first operand, destroying the original contents.  The following code illustrates how to multiply two fields
together.
 
                    ZAP   PRODUCT,FIELD1
                    MP    PRODUCT,FIELD2
                    ...
            FIELD1  DS    PL5
            FIELD2  DS    PL3
            PRODUCT DS    PL8
 
When planning to multiply two fields, in this case FIELD1 and FIELD2, you must plan for a field which is large enough to hold the
product.  The rule of thumb is that the length of the product field should be at least as large as the size of the multiplier length plus
the multiplicand length.  In the example above we compute the product length to be  5 + 3 = 8.  The first step is to copy the
multiplicand to the work field with the ZAP instruction.  The operation is then completed by executing the MP instruction.
 
   While Operand 1 ( containing the multiplicand ) can be as large as 16 bytes, Operand 2 (containing the multiplier ) is limited to a
maximum of 8 bytes.
 
   The MP instruction will cause your program to abend if there are not enough leading 0’s in the multiplicand prior to
multiplication.  The rule is that, prior to multiplying, there must be at least as many bytes of leading 0’s in the multiplicand as there
are bytes in the multiplier.  Consider the following example,
 
                    MP    PRODUCT,FIELDB     ABEND!
                    ...
            PRODUCT DC    X’00001234567C’
            FIELDB  DC    X’00887C’
 
The multiply instruction above causes an interrupt and the program abends  because the multiplicand contains only 2 bytes of
leading 0’s, while the multiplier is 3 bytes in length.
 
Dividing Packed Decimal Fields
 
   Use the DP mnemonic for the division of packed decimal fields.  Initially, Operand 1 is initialized with the dividend and the divisor
occupies Operand 2.  After the divide operation, Operand 1 contains the quotient, followed immediately by the remainder.  Here is
an example division which computes X / Y..
 
                    ZAP   WORK,X      INITIALIZE WITH THE DIVIDEND
                    DP    WORK,Y      Y IS THE DIVISOR
                    ...
            WORK    DS   0CL8         GROUP FIELD
            QUOT    DS    PL5         QUOTIENT OF X / Y
            REM     DS    PL3         REMAINDER OF X / Y
            X       DS    PL5
            Y       DS    PL3
 
You must plan the size of each work area when dividing.  In the example above, we are dividing a packed length 5 field by a
packed length 3 field.  The work area in which the division will occur must be large enough to contain a quotient and a remainder. 
How big could the quotient become?  Since we are performing integer arithmetic, the quotient could be the same size as the
dividend (consider division by 1).  How big could the remainder become?  The largest remainder is always one less than the
divisor, but the field size of the remainder might be just as large as the divisor.  Because of these considerations, the work area
size should be at least as large as the size of the dividend plus the size of the divisor.  In the code above, we made WORK  eight
bytes since the dividend was 5 bytes and the divisor was 3. 
 
   The first step was to ZAP the work area with the dividend, and then divide by Y.  Suppose X      initially contains X’000012356C’
and Y contains X’00100C’.   After the division, WORK will contain X’000000123C00056C’.  Notice that WORK is no longer packed,
but contains two packed fields.  It is a common error to reference the work area as a packed field after the division.  This is a
mistake which causes the program to abend.
 
   Using the definition of WORK above, the following division would produce an error, eventually.
 
                    ZAP   WORK,=P’123456’
                    DP    WORK,=PL2’100’
 
The problem arises because the remainder’s size is completely determined by the divisor’s size.  Since we divided by a 2
byte field, the remainder will occupy 2 bytes of WORK and the quotient fills the other 6 bytes.  After the division, WORK contains
X’00000001234C056C’, but the field definitions of QUOT AND REM do not match these results.  A future reference to either of

http://csc.columbusstate.edu/woolbright/PKARITH.HTM[9/21/2011 4:21:56 PM]


packed decimal arithmetic
Contents
these fields as a packed decimal value will cause an abend.
 
 
 
Shifting Packed Decimal Fields
 
   Since decimal points are not stored internally for packed decimal fields, and since packed decimal arithmetic is integer arithmetic,
it is necessary for an assembler programmer to shift fields left and right in order to obtain the precision required for most
calculations.  This is accomplished with the shift and round pack instruction which has mnemonic SRP.  ( Some shifts can be
completed using the MVO instruction, but SRP is easier to use and offers more flexibility.)   Using SRP, a packed decimal field can
be shifted left or right while leaving the sign digit fixed.  For right shifts, digits are lost on the right and 0’s fill in for digits which are
shifted out on the left.  For left shifts, leading 0’s are lost on the left and 0’s fill in for digits shifted out on the right.   
 
   The instruction has three operands:  Operand 1 is the field that will be shifted, Operand 2 is the shift factor, and Operand 3 is a
rounding factor for right shifts.  The shift factor is a 6-bit 2’s complement integer that we will represent as a decimal integer
between 1 and 31 for left shifts, and as 64 - n for right shifts of n digits. Operand 3, the rounding factor, is an integer from 0 to 9
that is added to the leftmost digit which is shifted out during a right shift.  Any carry is propagated through the rest of Operand 1.
Consider the following example.
 
                    SRP   P,3,5        P = X’000123000C’
                    SRP   Q,64-3,5     Q = X’0000010C’
                    ...
            P       DC    PL5’123’     P = X’000000123C’
            Q       DC    PL4’9876     Q = X’0009876C’
 
In the first SRP, the shift factor of 3 indicates a left shift by 3 digits.  Three digits are lost on the left and 3 zero digits are shifted in
on the right.  This shift is logically equivalent to multiplying by 1000.  In the second SRP, the shift factor of 64 - 3 indicates a right
shift by 3 digits.  The 8, 7, and 6 are shifted off.  Before shifting off the 8 which is the leftmost digit, the rounding factor of 5 is
added to the contents of P.  This addition causes a carry and creates the number 103 which is shifted, leaving a value of 10 in P.
 
   Shifting is commonly used when working with integers that contain decimal points.  Consider the problem of multiplying S and T,
and leaving a product that contains 1 digit to the right of the decimal point.  Remember that the machine does not store decimal
points internally for packed decimal fields.
 
             ZAP   PRODUCT,S       INITIALIZE THE MULTIPLICAND
             MP    PRODUCT,T       ...2 DIGITS TO RIGHT OF DECIMAL PT
             SRP   PRODUCT,64-1,0  REMOVE ONE DIGIT WITHOUT ROUNDING
             ...
    S        DC    PL3’1234.5’    S = X’12345C’  NO DECIMAL PT
    T        DC    PL2’10.0’      T = X’100C’    NO DECIMAL PT
    PRODUCT  DS    PL5
 
First the multiplicand is ZAPed into a 5 byte field called PRODUCT which is large enough to hold the product of S and T.  The
multiplication leaves PRODUCT with 2 digits to the right of the decimal point ( PRODUCT = X’001234500C’).  The SRP shift out
the rightmost digit leaving PRODUCT = X’000123450C’.  This result could be edited using ED or EDMK and the decimal point
could be inserted for printed output.
   
   Arithmetic on packed decimal fields that “contain” decimal points requires some careful thought on the programmer’s part. 
Consider dividing 123.4 by 2.1 using integer arithmetic.  Assume that after the division we would like the quotient to contain 1
decimal digit to the right of the decimal point.  We illustrate two possible divisions below.
 

http://csc.columbusstate.edu/woolbright/PKARITH.HTM[9/21/2011 4:21:56 PM]


packed decimal arithmetic
Contents
 
 
Keep in mind that decimal points are not stored internally.  The first division illustrates dividing 2.1 into 123.4 .  Since we are
working with integers, this is equivalent to dividing 21 into 1234.  The result is 58 and contains no decimal point.  This will not give
us the precision we demand in the quotient.  In the second division, by shifting the dividend to the left by one digit (bringing in a 0
on the right), we are effectively dividing 21 into 12340, and producing a quotient of 587 which could be edited to 58.7 for printing.
 
   The code below illustrates how the above division might appear in assembly language.
 
                    ZAP   WORK,M        M IS THE DIVIDEND
                    SRP   WORK,1,0      M NEEDS MORE PRECISION
                    DP    WORK,N        N IS THE DIVISOR
                    MVC   QUOTOUT,EDWD  EDIT WORD GOES TO OUTPUT AREA
                    ED    QUOTOUT,QUOT  PREPARE QUOTIENT FOR PRINTING
                    ...
            M       DC    PL4’123.4’    M = X’0001234C’  (NO DECIMAL PT)
            N       DC    PL2’2.1’      N = X’021C’   (NO DECIMAL PT)
            WORK    DS   0CL6           WORK FIELD FOR DIVISION
            QUOT    DS    PL4           QUOTIENT
            REM     DS    PL2           REMAINDER
            QUOTOUT DS    CL9
            EDWD    DC    X’402020202021204B20’
 
The work area field was designed as 6 bytes since the dividend was 4 bytes and the divisor was 2 bytes.  The dividend was
moved to the work area and then shifted left for more precision.  After the division, QUOT has the answer we would like to print. 
An edit word is created which matches the 4 byte packed field QUOT, and moved to an output area.  QUOT is then edited into the
output area. ( See ED for details on editing.)
 
   Next we consider the problem of generating an answer that is rounded to a specified precision.  Suppose we are going to divide
1234.56 by 2.1 and we would like to compute the quotient rounded to two decimal places to the right of the decimal point.  If we
simply divide,  the quotient would have 1 digit to the right of the decimal point.  In order to finish with a quotient that has two digits
rounded, we must generate 3 digits to the right of the decimal point before we divide.  We can achieve this precision by shifting to
the left by 2 digits before dividing.  The following code illustrates this idea.
 
                 ZAP    WORK,X          PREPARE THE DIVIDEND
                 SRP    WORK,2,0        SHIFT IN 2 0’S ON THE RIGHT
                 DP     WORK,Y          Y IS THE DIVISOR
                 SRP    QUOT,64-1,5     SHIFT RIGHT BY 1 AND ROUND
                 ...
        X        DC     PL4’1234.56’    X = X’0123456C’ (NO DECIMAL PT)
        Y        DC     PL2’2.1’        Y = X’021C’  (NO DECIMAL PT)
                 WORK      DS    0CL7     WORK AREA FOR DIVISION
                 QUOT      DS     PL5     QUOTIENT
                 REM       DS     PL2     REMAINDER
 
Why was WORK created as a 7 byte field when X contained 4 bytes and Y contained 2 bytes?  The reason is that after moving X
to WORK, we shifted it to the left by 2 digits, effectively making it a 5 byte field.  Making WORK a 7 byte field insures we have
enough room in the work area for the division.  Since we divided by a 2 byte field, the remainder has 2 bytes and the rest of the
work area is the quotient.  
 
   As a final example of handling decimal points, consider the problem of computing M times N and dividing the result by P.  We
would like the final answer to have 2 decimals to the right of the decimal point, rounded.  The declarations of M, N, and P are listed
below with the comments indicating the precision in each field.
 
                 M         DS     PL4     99999.99
                 N         DS     PL3     9999.9
                 P         DS     PL2     99.9
 
If we simply multiply M and N, the product will have 3 decimal places to the right of the decimal point.  Dividing by P would reduce
the number to 2.  In order to finish with an answer that has 2 decimals rounded, we need 3 digits before shifting.  That means the
product must be shifted to the left by 1 digit before the division.  The following code could be used.
 
                 ZAP   WORK,M        M IS THE MULTIPLICAND
                 MP    WORK,N        COMPUTE THE PRODUCT
                 SRP   WORK,1,0      SHIFT IN A ZERO ON THE RIGHT
                 DP    WORK,P        QUOTIENT WILL HAVE 3 DECIMAL PLACES
                 SRP   QUOT,64-1,5   ROUND QUOTIENT BACK TO 2 DIGITS
                 ....
         WORK    DS   0CL10          WORK AREA

http://csc.columbusstate.edu/woolbright/PKARITH.HTM[9/21/2011 4:21:56 PM]


packed decimal arithmetic
Contents
         QUOT    DS    PL8           QUOTIENT
         REM     DS    PL2           REMAINDER
 
Again, shifting the product left means the work area needs to be adjusted by one byte.
                   

http://csc.columbusstate.edu/woolbright/PKARITH.HTM[9/21/2011 4:21:56 PM]


instruction formats
Contents

 
   Internal memory on an IBM mainframe is organized as a sequential collection of bytes.  The bytes are numbered starting with 0
as pictured below,
 

The IBM System 370 architecture allows an address to be expressed as a collection of 31 consecutive bits.  The smallest address
would be represented by 31 consecutive 0’s which denotes address 0.  The largest address would be represented by 31
consecutive 1’s whose value is 2 31 - 1 = 2,147,483,647.  If we work with addresses in this form (lets call these direct addresses),
each address occupies a fullword - 4 bytes. 
 
   Why do we need an address in the first place?  Consider  the following instruction,
 
                     MVC  COSTOUT,COSTIN 
 
In order for the machine to move the contents of COSTIN to COSTOUT, it must know the locations of these two fields.  The
computer identifies a field by the address of the first byte in the field.  When an instruction is assembled, the assembler converts
any symbols like “COSTOUT” to their corresponding addresses.  The assembler does not, however, generate direct addresses, but
produces an address in base / displacement format.  Addresses in this form consist of 4 hexadecimal digits or two bytes, BDDD,
where B represents a base register and DDD represents a displacement.  The smallest displacement is x’000’ = 0 and the largest
displacement is x’FFF’ = 4095.  Ultimately, the base / displacement address must be converted to a direct address.  How does this
occur?  The diagram below indicates how this process takes place starting with the base/displacement address x’8003’.

Notice that the effective address, which is the direct address equivalent to the base/displacement address, is computed by adding
the contents of the base register with the specified displacement.
 
          Effective address  = Contents( Base Register)  +  Displacement
 
   There are two advantages of using base/displacement addresses instead of direct addresses in the object code that the
assembler produces:
 
   1)  Every address is shorter.  Instead of being 4 bytes long, the addresses are only 2 bytes.
 

http://csc.columbusstate.edu/woolbright/INSTRUCT.HTM[9/21/2011 4:21:58 PM]


instruction formats
Contents
   2)  The base/displacement addresses are correct no matter where the program is loaded in
         memory.  Each symbol is represented by a displacement from a fixed point inside the
         program.  If the program is relocated in memory, the displacement to a given variable does
         not change.  The base register remains fixed as well.  As a result, the base/displacement
         address is correct.  On the other hand, if we had used direct addresses, every symbol
         would have a new address if the program were relocated.  
 
     

http://csc.columbusstate.edu/woolbright/INSTRUCT.HTM[9/21/2011 4:21:58 PM]


DSECTS
Contents

 
    A  DSECT or Dummy Section provides the programmer with the ability to describe the layout of an area of storage without
reserving virtual storage for the area that is described.  The DSECT layout can then be used to reference any area of storage
which is addressable by the program.  Think of the DSECT as a template, or pattern, which can be “dropped” on any area of
storage.  Once the DSECT is “positioned”, the symbolic names in the DSECT can be used to extract data from the underlying
storage area. 
 
   How is the DSECT positioned?  This is a two-step process.  First, a register is associated with the DSECT name by coding a
USING directive.  Loading the register with the storage address completes the process.  Consider the sample code below.
 
                  CUSTOMER DSECT
                  FNAME    DS    CL4    
                  LNAME    DS    CL5
                  BALANCE  DS    PL5
                  MAIN     CSECT
                           ...
                           USING  CUSTOMER,R7
                           LA     R7,TABLE
                           MVC    NAME1,FNAME
                           MVC    NAME2,LNAME
                           ...
                  TABLE    EQU    *
                           DC     CL4’FRED’
                           DC     CL5’SMITH’
                           DC     PL5’432.98’
                           ...
                  NAME1    DS     CL10
                  NAME2    DS     CL20
 
   The “CUSTOMER” DSECT is created by coding the DSECT directive which indicates the beginning of the dummy section.  The
general format for this directive is listed below.
 
                  NAME           OPERATION     OPERAND
 
                  Any Symbol     DSECT       Not required
 
The pattern for the DSECT is created using a series of DS directives to describe a collection of fields in storage.  The end of the
DSECT is indicated by the beginning of the CSECT.  While the DSECT can be coded almost anywhere in the program, it is a
common practice to place any DSECTs you will need above the main control section, as in the example above.  In order to code a
DSECT in the “middle” of a control section, the CSECT directive would appear twice as indicated below.
                  MAIN     CSECT
                           ...
                  CUSTOMER DSECT
                  FNAME    DS    CL4
                  LNAME    DS    CL5
                  BALANCE  DS    PL5
                  MAIN     CSECT
The second CSECT directive indicates that the “MAIN” control section is being continued.
 
   After defining the dummy section, it must be associated with an available register in a USING directive.  In the example code
above, the statement “USING   CUSTOMER,R7” associates register seven with the “CUSTOMER” dummy section.  Addressability
is established when the register is loaded with the address of the table.  At that point, FNAME  contains the value “FRED”, and
LNAME contains the value “SMITH”.  Loading the register “drops” the DSECT on the storage area whose address is contained in
the register.
 
   You should consider the power of the above technique.  There were no symbolic names associated with the table when it was
defined.  By creating a DSECT, we are able to dynamically assign symbols to an area of storage and retrieve the data the area
contains.  DSECTs have many uses in assembly language including array processing, locate mode I/O ( See SEQUENTIAL FILE
PROCESSING ), and data structure creation and manipulation.  Most sophisticated  assembler programs involve DSECTS to some
degree. Because of their importance, we will consider the use of DSECTs in array processing.
 

http://csc.columbusstate.edu/woolbright/DSECTS.HTM[9/21/2011 4:21:58 PM]


DSECTS
Contents
Loading an Array With Data
 
   In the following example we will load an “empty” storage area with data that is read from a file.  We will use the same DSECT as
in the previous example.
 
              CUSTOMER DSECT
              FNAME    DS    CL4    
              LNAME    DS    CL5
              BALANCE  DS    PL5
              CRECLEN  EQU   *-CUSTOMER
              MAIN     CSECT
                       ...
                       USING  CUSTOMER,R7
                       LA     R7,TABLE        POSITION THE DSECT
                       LA     R4,CRECLEN      LOAD # OF RECS INTO R4
              LOOP     EQU    *
                       GET    FILEIN,RECIN    READ A RECORD
                       MVC    FNAME,FNAMEIN   MOVE DATA ...
                       MVC    LNAME,LNAMEIN   ... FROM RECIN ...
                       ZAP    BALANCE,BALIN   ... TO THE TABLE
                       LA     R7,CRECLEN(R0,R7)  BUMP THE DSECT
                       BCT    R4,LOOP         BRANCH BACK IF MORE RECS
                       ...
              TABLE    DS  100CL(CRECLEN) EMPTY AREA FOR 100 RECORDS  
 
   The address of the empty table is placed in R7 by the first LA instruction.  This has the effect of positioning the DSECT at the
beginning of the table area, since the USING directive associated register seven with the DSECT name. The length of a typical
table entry is computed as “CRECLEN” using a EQUATE directive and placed in R4 by the LA instruction.  A record is retrieved
and the data is moved from the input buffer, RECIN, and placed in the table using the symbolic names that were defined in the
DSECT.
 
   In order to move the DSECT to the next empty table entry we code the following line,
 
             LA     R7,CRECLEN(R0,R7)  BUMP THE DSECT
 
This type of statement is used quite often in DSECT processing and so we consider it in some detail.  The statement uses explicit
addressing and the technique is considered acceptable practice.  The effect is to compute the second operand address explicitly
from the base register (R7), index register (R0), and displacement (CRECLEN).  When R0 is specified as an index register, that
component of the address computation is ignored.  The “effective” address that would be computed consists of the contents of R7
plus the displacement of 14 represented by CRECLEN.  Since R7 contains the address of a table entry, adding 14 to R7 will create
the address of the next table entry.  The DSECT has been “bumped” down to the next table entry.
 
   The BCT instruction is used for loop control, and insures that each entry in the table is filled. 
 
 
  
 

http://csc.columbusstate.edu/woolbright/DSECTS.HTM[9/21/2011 4:21:58 PM]


explicit addressing
Contents

 
   The term explicit addressing refers to the practice of representing the address of a byte in memory by specifying a base
register and a displacement, or a base and index register and a displacement.  If at all possible, we would prefer to represent a
byte in memory by a symbolic name.  Usually this is possible.  For instance, consider the following declaration,
 
                    XFIELD   DS    CL5
 
While it does have a length attribute of five, the symbol “XFIELD” represents the address of the first byte of that field.  This is
important to understand because the assembler will convert this symbolic address to a base/displacement format representing the
address of the first byte of the field.  This base/displacement address (BDDD in hexadecimal) occupies two bytes in the
assembled code as evidenced in the instruction formats. (See the instruction format for an SS instruction.)  
  
   Unfortunately, sometimes the use of a symbolic name like XFIELD is inconvenient or impossible to create.  At these times we
must resort to an explicit address.  The explicit format for each instruction in this text is provided at the top left of the title page for
each instruction.  For example, the MVC instruction lists the following explicit format.
 

 
Consider the following example instruction.
 
                    MVC   4(8,12),32(8)
 
Using the explicit format above we can decipher what the instruction will do.  First, we can see that it is a move instruction that will
transfer 8 bytes.  Where will the data that is to be moved come from?  The answer is given explicitly as 32(8).  This is a 32 byte
displacement off register 8.  At execution, the effective address is computed by adding the contents of base register 8 plus the 32
byte displacement:
 
                  Effective address =  Contents(Base register 8)  +  32
 
At “execution time” it is imperative that register 8 contains a “known” address and that the second operand field that we are
currently addressing be 32 bytes away from this known address.
 
   Where will the data be moved?  Again, the answer is given explicitly as 4(12).  This represents a 12 byte displacement off
register 12.  The effective address is computed to be the contents of base register 12 plus 4.  The field which is to receive the data
must be at an address which is 4 bytes larger than the “execution time” address in register 12.
 
   Each instruction format has its own explicit format.  For instance, the load instruction appears below.
 

http://csc.columbusstate.edu/woolbright/EXPLICIT.HTM[9/21/2011 4:21:59 PM]


explicit addressing
Contents

 
Consider the following explicitly coded instruction,
 
                    L   10,4(3,5)
 
Obviously, register 10 is being loaded with a fullword in memory.  Where is the fullword stored?  The explicit format gives the
answer.  The base register is 5, register 3 is an index register, and 4 is a displacement.  The effective address can be computed
by adding the contents of the base register, plus the contents of the index register, plus the displacement:
 
                          Effective Address = Contents(register 5) + Contents(register 3) + 4
 
   A knowledge of the explicit notation is helpful in understanding many instructions.  For instance, it is common practice for an
assembler programmer to code an instruction similar to the one below.
 
                    LA   R5,10
 
Without prior knowledge, what are we to make of this code?   First we could look up a load address instruction and discover that it
is an RX instruction and has an explicit format similar to the load instruction described above.  The second operand for an RX
instruction appears as D2(X2,B2).  The instruction above has no parentheses - they were omitted.  This means that 10 is a
displacement.  What is the effective address?  Since the base and index registers were omitted, zero was chosen for the base and
index registers.  But the machine never uses register zero as a base or index register.  This means that the effective address is
simply 10.  The effect of the instruction above is to load a “small” number into register 5.  Experienced programmers understand
this and choose the method as an effective way to load “small” numbers.  What is meant by “small”?  Since the number we are
loading must appear as a displacement, the largest number we could code in this way is 4095  = X’FFF’ which is the maximum
displacement allowed.       
 
Mixing Symbolic and Explicit Notation
 
   It is also possible to mix symbols and explicit notation within the same instruction.  For example,
 
                    L    8,XWORD(5)
 
In the load instruction above, 8 is the Operand 1 register where a fullword will be loaded.  What does the notation XWORD(5)
mean?  In all cases, the assembler can process a symbol like XWORD and produce a base register and a displacement.  This
means that the 5 is an index register.  A related example appears below.
 
                    MVC   AFIELD(8),BFIELD
 
Operand 1 appears as AFIELD(8).  Again, the assembler can process the symbol AFIELD and produce a base register and a
displacement.  Checking the explicit notation for a move character instruction we see that the 8 must be the length of Operand 1. 
Normally, the length would be taken from the length attribute of AFIELD.  Mixing notations allows us to overide the “implicit” length
with an “explicit” length.
 

 
          L     14,12,12(R13)  14 AND 12 REPRESENT A RANGE OF REGISTERS.
                               WORDS ARE LOADED BEGINNING WITH THE WORD
                               12 BYTES OFF REGISTER 13.
 
          MVC   X(9),Y         A 9 BYTE EXPLICIT LENGTH

http://csc.columbusstate.edu/woolbright/EXPLICIT.HTM[9/21/2011 4:21:59 PM]


explicit addressing
Contents
          L     R8,9           AN ERROR - TRIES TO LOAD THE WORD AT
                               ADDRESS 9.
          LA    R8,9           BETTER!  LOADS 9 INTO REGISTER 8
          AP    X(4),Y(3)      SS2 INSTRUCTIONS HAVE TWO LENGHTS
          MVI   0(R8),C’ ’     MOVES A BLANK TO THE ADDRESS IN R8
          BASR  R12,R0         RR INSTRUCTIONS ARE ALWAYS EXPLICIT
 

1)  Avoid the use of explicit notation whenever possible to simplify your code.
 
2)  If you must use explicit notation, always code base and index registers using equate names (R0, R1, ...). This practice was not
followed in the notes above (examples excluded) in order to emphasize the explicit nature of the code.  Using equate names forces
the assembler to record the use of each register in the cross reference listing at the end of your program.  For large programs this
is a necessity.
 
3)  One of the primary uses for explicit addresses involves parameter passing.  In this area, the use of explicit addresses is a
commonly accepted practice.  Read  Program Linkage and become familiar with this important use of explicit addresses.
 
4)  Consider the use of a DSECT as a means of using symbolic names instead of coding  explicit addresses.
 
5)  Remember that explicit addresses must be used if you have not issued a USING directive or if no base register is available.
(See Base Displacement Addressing.)

http://csc.columbusstate.edu/woolbright/EXPLICIT.HTM[9/21/2011 4:21:59 PM]


instruction formats
Contents

 
   When the assembler processes an instruction, it converts the instruction from its mnemonic form to a standard machine-language
(binary) format called an “instruction format”.  In the process of conversion, the assembler must determine the type of instruction,
convert symbolic labels and explicit notation to a base/displacement format, determine lengths of certain operands, and parse any
literals and constants.  Consider the following “Move Characters” instruction,
 
                                                      MVC   COSTOUT,COSTIN
 
The assembler must determine the operation code (x’D2’) for MVC, determine the length of COSTOUT, and compute
base/displacement addresses for both operands.  After assembly, the result which is called “object code”, might look something like
the following in hexadecimal,
 
                                                      D207C008C020
 
The assembler generated 6 bytes (12 hex digits) of object code in a storage to storage (type one) format.  In order to understand
the object code which an assembler will generate, we need some familiarity with 5 basic instruction formats (there are other
instruction types covering privileged and semiprivileged instructions which are beyond the scope of this discussion). 
 
   First we consider the Storage to Storage type one (SS 1 ) format listed below.  This is the instruction format for the MVC
instruction above.
 

      
                           
            
                Byte 1     -    machine operation code
                Byte 2     -    length -1 in bytes associated with operand 1
                Byte 3 and 4    -    the base/displacement address associated with operand 1
                Byte 5 and 6    -    the base/displacement address associated with operand 2
 
   Each box represents one byte or 8 bits and each letter represents a single hexadecimal digit or 4 bits.  The subscripts indicate
the number of the operand used in determining the contents of the byte.  For example, the instruction format indicates that operand
1 is used to compute L 1 L 1 , the length associated with the instruction.  If we reconsider the assembled form of the MVC instruction
above we see that the op-code is x‘D2’, and the length, derived from COSTOUT, is listed as x’07’.  Since the assembler always
decrements the length by 1 when converting to machine code, we determine that COSTOUT is 8 bytes long - 8 bytes will be
moved by this instruction.  Additionally we see that the base register for COSTOUT is x’C’ (register 12) and the displacement is
x’008’.  The base/displacement address for COSTIN is x’C020’.
 
  Why was register 12 chosen as the base register?  How were the displacements computed?  These parts of the object code
could not be determined by the information given in the example above.  In order to determine base/displacement addresses we
must examine the “USING” and “DROP” directives that are coded in the program.  These directives are discussed in the topic
called BASE DISPLACEMENT ADDRESSING.
   Being able to read object code is a necessary skill for an assembler programmer.  Knowledge of an instruction’s format gives
several important clues about the instruction.  For example, knowing that MVC is a storage to storage type one instruction, informs
us that both operands are fields in memory and that the first operand will determine the number of bytes that will be moved.  Since
the length (L 1 L 1 ) occupies one byte or 8 bits, the maximum length we can create is 2 8 - 1 = 255 .  Recall that the assembler
decrements the length when assembling, so the instruction is capable of moving  a maximum of 256 bytes.  The 256 byte limitation
is shared by all storage to storage type one instructions.
 
   Storage to Storage type two (SS 2 ) is a variation on SS 1 . 
 
 

http://csc.columbusstate.edu/woolbright/INSTORG.HTM[9/21/2011 4:22:01 PM]


instruction formats
Contents

      
                           
            
                Byte 1     -    machine operation code
                Byte 2     -    L 1   - the length associated with operand 1 (4 bits)
                                    L 2   - the length associated with operand 2  (4 bits)
                Byte 3 and 4    -    the base/displacement address associated with operand 1
                Byte 5 and 6    -    the base/displacement address associated with operand 2
 
    The only difference between SS 1 and SS 2  is the length byte.  Notice that both operands contribute a length in the second
byte.  Since each length is 4 bits, the maximum value that could be represented is 2 4 - 1 = 15.  Again, since the assembler
decrements the length by 1, the instruction can process operands that are large as 16 bytes.  There are many arithmetic
instructions that require the machine to use the length of both operands.  Consider the example below,
                               
             Object Code               Source Code
 
                       AFIELD   DS    PL4
                       BFIELD   DS    PL2
                                ...
      FA31C300C304              AP    AFIELD,BFIELD 
 
   AP  (Add Packed) is an instruction whose format is SS 2 .  Looking at the object code that was generated,  we see that x’FA’ is
the op-code and that the length of the first operand is x’3’ which was computed by subtracting 1 from the length of AFIELD. 
Similarly, the length of BFIELD was used to generate the second length of x’1’.  In executing this instruction, the machine makes
use of the size of both fields.  In this case, a 2 byte field is added to a 4 byte field.
 
   A second type of instruction format is Register to Register (RR).
 

                                   
 
                Byte 1     -    machine operation code
                Byte 2     -    R1 - the register which is operand 1
                                    R2 - the register which is operand 2
 
   Instructions of this type have two operands, both of which are registers.  An example of an instruction of this type is LR (Load
Register).  The effect of the instruction is to copy the contents of the register specified by operand 2 into the register specified by
operand 1.  The following LR (Load Register) instruction,
 
                          LR    R3,R12
 
would cause register 12 to be copied into register 3.  The assembler would produce the object code listed below as a result of the
LR instruction.
 
                                                      183C
 
Examining the object code we see that the op-code is x’18’ , operand 1 is register 3, and operand 2 is register 12.  You should
note that 4 bits are enough to represent any of the registers which are numbered 0 through 15.
 
   A third type of  instruction format is Register to Indexed Storage (RX).
 

                                              
 
                Byte 1     -    machine operation code
                Byte 2     -    R 1   - the register which is operand 1
                                    X2   - the index register associated with operand 2

http://csc.columbusstate.edu/woolbright/INSTORG.HTM[9/21/2011 4:22:01 PM]


instruction formats
Contents
                Byte 3 and 4    -    the base/displacement address associated with operand 2
 
For instructions of this type, the first operand is a register and the second operand is a storage location.  The storage location is
designated by a base/displacement address as well as an index register.  The subject of index registers is discussed in the topic
BASE DISPLACEMENT ADDRESSING.  L (Load) is an example of an instruction of type RX.  Consider the example below.
 
                         L    R5,TABLE(R7)
 
The Load instruction copies a fullword from memory into a register.  The above instruction might assemble as follows,
               
                         5857C008
 
The op-code is x’58’, operand 1 is specified as x’5’, the index register is denoted x’7’ and  Operand 2 generates the
base/displacement address x’C008’.  Again, from the information given in the example above, there is no way to determine how the
base/displacement address was computed.
 
   Related to the RX type is a similar instruction format called Register to Storage (RS).  In this type the index register is replaced
by a register reference or a 4-bit mask (pattern).
 
 

                                        
 
   One instruction which  has a Register to Storage format is STM (Store Multiple).  An example of how STM can be coded is as
follows,
 
                       STM    R14,R12,12(R13)
The previous instruction would generate the following object code,
 
                                                   90ECD00C
 
where x’90’ is the op-code,  x’E’ = 14 is operand 1, x’C’ = 12, is treated as R 3 , and x’D00C’ is generated from an explicit
base/displacement address (12(R13)).    
 
 
   The fifth and final instruction format that we will consider is called Storage Immediate (SI).  In this format, the second operand,
called the immediate constant, resides in the second byte of the instruction.  This constant is usually specified as a self-defining
term. 
 
The format for SI instructions is listed below.
 

                                         
 
                Byte 1     -    machine operation code
                Byte 2     -   I2 I2 - the immediate constant denoted in operand 2
                Byte 3 and 4    -    the base/displacement address associated with operand 1
 
   An example of a storage immediate instruction is Compare Logical Immediate (CLI).  This instruction will compare one byte in
storage to the immediate byte which resides in the instruction itself.  We see from the instruction format that operand 2 is the
immediate constant.  For example, consider the instruction below.
 
                         CLI    CUSTTYPE,C’A’
 
When assembled, the object code might look like the following,
 
                         95C1C100
 
The op-code is x’95’, the self-defining term C’A’ is converted to the EBCDIC representation x’C1’, and the variable CUSTTYPE

http://csc.columbusstate.edu/woolbright/INSTORG.HTM[9/21/2011 4:22:01 PM]


instruction formats
Contents
would generate the base/displacement address x’C100’.  Again, there is not enough information provided to determine the exact
base/displacement address for CUSTTYPE.  The x’C100’ address is merely an example of what might be generated.        

http://csc.columbusstate.edu/woolbright/INSTORG.HTM[9/21/2011 4:22:01 PM]


linkage
Contents

 
   The term “program linkage” or simply “linkage” encompasses all the techniques required to make separately assembled control
sections work cooperatively.  This includes transfers of execution between control sections as well as the communication of data
between control sections or programs.  To facilitate program linkage, IBM developed a series of rules called “Linkage Conventions”
which specify the responsibilities of the cooperating programs.  We will call the main program the “calling program” and the
subroutine it calls the “called program”.  Each type of program has it own conventions. 
 
The Calling Program’s Conventions
 
1)  Register 13 should contain the address of a “Save Area”.  The save area is a contiguous collection of 18 fullwords that is used
as a storage area for the registers.  Since there are only 16 registers which must be shared by all programs, the calling program
must provide the address of its save area in register 13.  Subsequently, the called program stores the contents of the registers in
this area before continuing execution.
 
2)  Register 15 should contain the entry point address of the called program.  Since the entry point is not in the calling program,
we must use a “virtual” address constant in order to reference the entry point.  For example, suppose the entry point in the called
program is the CSECT name “SUBPROG”.   Then the following instruction would load register 15 properly.
 
                     L     R15,=V(SUBPROG)
 
When the assembler processes the virtual address constant, it recognizes that the symbol SUBPROG is not part of the current
control section.  As a result it assembles a fullword containing zeros for the virtual address.  When the linkage editor combines the
calling and called subprograms, the fullword is filled in with the correct runtime address of SUBPROG.  Only “external” symbols can
be used for entry points into a control section.  Control section names are automatically external.  Other symbols can be declared
external using the EXTRN directive.
 
3)  When passing variables from the main program to the subprogram, the address of each variable we wish to pass becomes an
entry in a list of consecutive fullword addresses.  The address of the list is placed in register 1.  Assume we want to pass variables
X, Y, and Z.  The following code will create the address list and initialize register 1.
 
                     LA     R1,=A(X,Y,Z)
 
The following diagram illustrates the structure which is created by the above command. We assume the following declarations.
 
                     X      DC    CL3’ABC’
                     Y      DC    CL2’PQ’
                     Z      DC    CL4’DEFG’

http://csc.columbusstate.edu/woolbright/LINKAGE.HTM[9/21/2011 4:22:02 PM]


linkage
Contents

 
 
Notice that only one item of data is passed -  the address of the list of addresses.  You must use register 1 to find all the variables
which are passed.
 
4)  Register 14 should be initialized with the “return” address.  This is the address to which the called program will transfer control
when it has completed execution.  The following instruction will accomplish this.
 
                     BASR   R14,R15
 
BASR stores the address of the instruction following the BASR in register 14, and branches to the address in register 15.  In this
way, control is transferred to the subprogram.
 
The Called Program’s Conventions
 
1)  The called program must save the current values of the registers in the caller’s save area.  Since the caller has placed the
address of the save area in register 13, the following code will save the registers.
 
                     STM    R14,R12,12(R13)
 
Notice that the explicit address 12(R13) means that R14 is stored in the fourth fullword in the save area ( 12 bytes off R13 ). You
should also note that all the registers are stored except R13.  Register 13 contains the address of the save area and must be
stored in an area that belongs in the called program.
 
The format of the save area is listed below.  We assume a sequence of program calls:  Program “A” calls Program “B”, and
Program “B” calls Program “C”.  The save area in the diagram is for Program “B”.

http://csc.columbusstate.edu/woolbright/LINKAGE.HTM[9/21/2011 4:22:02 PM]


linkage
Contents

                                         
 
 
 
2)  The contents of register 13 ( the address of the caller’s save area ) must be stored in the second fullword of the called
program’s save area.  This can be done using the following instruction.
 
                        ST    R13,SAVE+4
 
Notice that “SAVE” refers to the save area in the called program.  “SAVE+4” becomes a “backwards pointer” to the previous save
area.  This is illustrated below.
 

                                      
 
Additionally, the called program can store the address of its own save area in the calling program’s save area in the third word
(SAVE+8).  This last technique is usually omitted and will not be used in this topic.
 
3)  Like the calling program, R13 should contain the address of the program’s save area.  This is accomplished with the same
instruction used in the main program.
 
                     LA    R13,SAVE
 
4)  Register 1 can be used to access any variables that are passed from the main program.  For example, suppose X, Y, and Z are
passed as parameters as described in step 3 of the “The Calling Program’s Conventions”.  Assume that Y is defined as CL2 in the
main program, and YSUB is defined as CL2 in the subprogram.  The data in Y can be copied to YSUB as follows.
 
             L    R8,4(R0,R1)    LOAD THE 2ND ADDRESS CONSTANT
             MVC  YSUB,0(R8)     R8 POINTS AT Y IN THE MAIN
 
The technique of copying a variable to the subprogram and working with the copy is called “Pass by Value”.  An alternative would
be to work directly with Y in the main program.  This technique is called “Pass by Reference”.  Either technique is acceptable

http://csc.columbusstate.edu/woolbright/LINKAGE.HTM[9/21/2011 4:22:02 PM]


linkage
Contents
according to the linkage conventions.  “Pass by Value” provides protection for the main program from “side effects” generated by
the subprogram.
 
5)  At the end of the subprogram the called program must restore the registers to the values that were stored in the save area. 
The following code will restore the registers.
 
                      L     R13,SAVE+4
                      LM    R14,R12,12(R13)
 
6)  The called program should initialize register 15 with a return code value to indicate the results of the subprogram.  Generally,
return codes are multiples of four - 0, 4, 8, ... where 0 indicates success, 4 is a warning, and all the other codes indicate that errors
have occurred.  The following command will initialize register 15 with a small ( < 4096 ) return code.
 
                      LA    R15,8       SET RETURN CODE TO 8
 
7)  The subprogram can return to the caller by branching to the return address that was stored in register 14 by the caller.
 
                      BR     R14
 
   The following code illustrates a calling and called program side by side.
 

MAIN     CSECT                           SUB      CSECT


         STM    R14,R12,12(13)                    STM    R14,R12,12(R13)
         BASR   R12,R0                            BASR   R12,R0
         USING  *,R12                             USING  *,R12
         ST     R13,SAVE+4                        ST     R13,SAVE+4
         LA     R13,SAVE                          LA     R13,SAVE
         ...                                      ...
         LA     R1,=A(X,Y,Z)                      L      R8,0(R0,R1)
         L      R15,=V(SUB)                       MVC    XSUB,0(R8)
         BASR   R14,R15                           L      R8,4(R0,R1)
         ...                                      MVC    YSUB,0(R8)
EXIT     EQU    *                                 L      R8,8(R0,R1)
         L      R13,SAVE+4                        MVC    ZSUB,0(R8)
         LM     R14,R12,12(R13)                   ...
         LA     R15,0                    EXIT     EQU    *
         BR     R14                               L      R13,SAVE+4
         ...                                      LM     R14,R12,12(R13)
X        DS     CL4                               LA     R15,0
         ...                                      BR     R14
Y        DS     CL2                      XSUB     DS     CL4
Z        DS     F                        YSUB     DS     CL2
SAVE     DS    18F                       ZSUB     DS     F
         END    MAIN                     SAVE     DS     18F
                                                  END    SUB

http://csc.columbusstate.edu/woolbright/LINKAGE.HTM[9/21/2011 4:22:02 PM]


linkage
Contents

1.  Each program you write should follow the calling program’s conventions as well as the called program’s conventions.  The
operating system treats each main program you write as a subprogram and so even a main program behaves as a subprogram. 
On the other hand, each subprogram you write may call other programs either explicitly or by requesting services from the
operating system. 
 
   Write each program as if it is one link in a chain of program calls.
 
 

http://csc.columbusstate.edu/woolbright/LINKAGE.HTM[9/21/2011 4:22:02 PM]


address constant
Contents

 
   Each byte of internal memory is numbered sequentially beginning with 0 for the first byte, 1 for the second byte, and continuing
in this way until the end of memory is reached.  We will call the number associated with each byte the address of the byte.  There
is a limit to the amount of memory that is supported, since addresses are expressed as binary integers using 31 bits.  The smallest
address which can be created is 0 and the maximum address is 2 31 - 1 which is 2,147,483,647 or 2 gigabytes.
 
   Address fields are created by using the A,Y, or V indicators in a DS or a DC.  (Q-constants and S-constants are discussed
elsewhere.)  If a length indicator is not coded, A and V indicate fullword fields, while Y indicates a halfword address. A length
indicator can be used to create A-constants with 1 to 4 bytes, V-constants with 3 or 4 bytes, and Y-constants with 1 or 2 bytes.
 
   The following are formats for creating address constants,
 
                                             name      DC    T( address, ... )
 
                                             name      DC    TLn( address, ...)
 
where “name” is a field name,
         “T” is the address type A,Y, or V,
         “address, ...” represents 1 or more addresses separated by commas.  Each address is
                              either a relocatable, a complex relocatable, or an absolute expression.
 
It is difficult to give the technical definition of the terms relocatable and complex relocatable, but generally, an expression is
relocatable if it refers to labels in a program and the value of the expression changes if the program is moved from its original
location.   An expression is absolute if it refers to labels in a program, and the value of the expression is constant regardless of
the location of the program.  An example will help with these ideas,
 
                DOG     DS    CL5
                CAT     DS    CL7
                PIG     DS    CL9
                ADR1    DC    A(PIG)        RELOCATABLE
                ADR2    DC    A(PIG - DOG)  ABSOLUTE
                ADR3    DC    A(PIG + DOG)  COMPLEX RELOCATABLE  
 
Notice that “ADR1” is relocatable since its value (address) would change if the program were moved.  “ADR2” is absolute since
PIG and DOG are 12 bytes apart regardless of where the program is loaded.  “ADR3” is complex relocatable since it involves
multiple “unpaired” relocatable expressions and its value would change depending on the program’s location.
 
   Relocatable expressions are initially created at assembly time and then modified by the linkage editior at link time to contain the
correct address for the expression you have created.  Absolute expressions are not modified by the linkage editor.
 
  The main difference between A-constants and V-constants is that a V-constant can refer to a label in a different control section. 
A-constants can only reference labels within the same control section.  For V-constants, at assembly time, the assembler creates a
fullword containing 0’s and leaves an indicator for the linkage editior to supply the correct address in the constant at link time.  The
primary reason for using a V-constant is for program linkage - we want to branch to a separately assembled control section.  This
can be accomplished with the code below,
 
               LA    R1,=A(X,Y,Z)       POINT TO THE PARAMETERS
               L     R15,=V(SUBPROG1)   VIRTUAL ADDRESS SUBPROG1
               BASR  R14,R15            BRANCH TO THE SUBPROGRAM
 
   Notice that the above example also uses A-constants to create 3 consecutive fullword addresses for parameter passing.
 
 

http://csc.columbusstate.edu/woolbright/ADCON.HTM[9/21/2011 4:22:03 PM]


address constant
Contents
          Some Typical DS’s and DC’s:
 
   TABSTART EQU   *
   GOAT     DS    CL8
   TABRECLN EQU   *-TABSTART
   HORSE    DS    CL8
   CAT      DS    CL8
   TABEND   EQU   *
   TABLEN   DC    A(TABEND - TABSTART)   Assemble table length
   TABLEN2  DC    AL2(TABEND - TABSTART) Halfword table length
   NORECS   DC    A((TABEND - TABSTART)/TABRECLN)  Number of entries
   P        DS    A            A fullword field, properly aligned
   Q        DS    AL4          A fullword field, no slack bytes
   R        DC    V(SUBPROG1)  The virtual address of SUBPROG1
   S        DC    A(CAT)       A relocatable address
   T        DC    A(CAT,HORSE,GOAT)  Three consecutive address constants
   U        DC    Y(HORSE)     A halfword address
   TRANTAB1 DC   256AL1(0)     A skeleton for a TRT table
   TRANTAB2 DC   256AL1(*-TRANTAB2)  A skeleton for a TR table
                                     x’000102030405060708090A...’

1.  Read the technical definitions of Relocatable, Complex Relocatable, and Absolute expressions found in IBM’s High Level
Assembler  Language Reference .

http://csc.columbusstate.edu/woolbright/ADCON.HTM[9/21/2011 4:22:03 PM]


add
Contents

 
 
   The Add instruction performs 2’s complement binary addition.  Operand 1 is a register containing a fullword integer.  Operand 2
specifies a fullword in memory.  The fullword in memory is added to the fullword in the register and the result is stored in the
register.  The fullword in memory is not changed.  Consider the following example,    
 
                            A    R9,AFIELD       
 

   The contents of the fullword “AFIELD”, x’0000000A’ = 10, are added to register 9 which contains x’00000025’ = 37.  The sum is
47 = x’0000002F’  and destroys the previous value in R9.  The fullword in memory is unchanged by this operation.
 
   Since A is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 

          Some Unrelated Adds


 
              R4 =  X’FFFFFFFE’   -2 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
  
              DOG   DC   F’4’
              CAT   DC   F’-4’
 
              A    R4,=F’20’    R4 = X’00000012’ = +18
              A    R5,=F’20’    R5 = X’0000003C’ = +60
              A    R6,=F’20’    R6 = X’00000018’ = +24
              A    R6,=F’-5’    R6 = X’FFFFFFFF’ = -1
              A    R6,CAT       R6 = X’00000000’ =  0
              A    R6,DOG       R6 = X’00000008’ = +8
              A    R6,DOG(R6)   R6 = X’00000000’  INDEXING IS ALLOWED

http://csc.columbusstate.edu/woolbright/ADD.HTM[9/21/2011 4:22:15 PM]


addhalf
Contents

 
   The Add Halfword instruction performs 2’s complement binary addition.  Operand 1 is a register containing a fullword integer. 
Operand 2 specifies a halfword in memory.  The halfword in memory is sign extended (internally) and added to the fullword in the
register.  In other words, it is converted to an arithmetically equivalent fullword before the addition.  The result is stored in the
register, while the halfword in memory is not changed.  Consider the following example,    
 
                            AH    R9,AFIELD       
 

   The contents of the halfword “AFIELD”, x’007F’ = 127, are added to register 9 which contains x’000003FA’ = 1018.  The sum is
1145 = x’00000479’  and destroys the previous value in R9.  The halfword in memory is unchanged by this operation.
 
   Since AH is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 

          Some Unrelated Add Halfwords


 
              R4 =  X’FFFFFFF6’  -10 IN 2’S COMPLEMENT
              R5 =  X’00000031’  +49 IN 2’S COMPLEMENT
              R6 =  X’00000008’  +8  IN 2’S COMPLEMENT
              DOG   DC   H’4’,H’9’,H’-25’,H’3’   CONSECUTIVE HALFWORDS
 
              AH    R4,=H’20’    R4 = X’0000000A’ = +10
              AH    R5,=H’20’    R5 = X’00000045’ = +69
              AH    R6,=H’20’    R6 = X’0000001C’ = +28
              AH    R6,=H’-9’    R6 = X’FFFFFFFF’ = -1
              AH    R4,DOG       R6 = X’FFFFFFFA’ = -6
              AH    R6,DOG       R6 = X’0000000C’ = +12
              AH    R4,DOG(R6)   R6 = X’FFFFFFDD’ = -35 INDEXING ALLOWED

   A common error is to code a AH when the second operand is not a halfword.  For example:
 
         AMOUNT    DC   F’20’        AMOUNT = X’00000014’
                   ...
                   AH   R5,AMOUNT
 
The assembler will not complain about your code, but the halfword instruction will only access the first two bytes of the AMOUNT
field (x’0000’).
 

http://csc.columbusstate.edu/woolbright/ADDHALF.HTM[9/21/2011 4:22:16 PM]


addpack
Contents

 
   AP is an SS 2 instruction which is used to add packed decimal fields.  Operand 1 is a field in storage which should contain a
packed decimal number.  The resulting sum develops in this field.  The contents of Operand 2, another packed decimal field in
storage, is added to the contents of Operand 1 to produce the sum which is stored in Operand 1.   The operands are limited to a
maximum length of 16 bytes and may have different sizes since this is a SS 2   instruction.
 
  A decimal overflow (condition code = 3) can occur if the generated sum loses a significant digit when it is placed in the target
field.  A decimal overflow may or may not cause a program interruption (abend).  This depends on the setting of a bit in the PSW
(See SPM).  Otherwise, the condition code is set to indicate whether the result was zero (condition code = 0), negative (condition
code = 1), or positive (condition code = 2).  You can test these conditions with BZ or BNZ, BM or BNM, and BP or BNP.
 
   Consider the following AP example.
 
                       AP      APK,BPK
                       BP      APOSITIV
 
Assume the variables are initially in  the following states,
 
              APK      DC      PL4’34’  = X’0000034C’
              BPK      DC      PL3’22’  = X’00022C’
 
After the AP instruction has executed,  the variables have the following values.
     
              APK  = X’0000056C’
              BPK  = X’00022C’
 
The contents of BPK and APK were added and the result stored in APK.  BPK was unaffected by the add operation.  The branch
would occur and execution would resume at “APOSITIV” since the condition code was set to positive.
 
   On the other hand, consider the following example,
 
                       AP      APK,BPK
                                                ...
              APK      DC      PL2’999’  = X’999C’
              BPK      DC      PL2’3’    = X’003C’
 
After the AP instruction has executed,  the variables have the following values.
     
              APK  = X’002C’
              BPK  = X’003C’
Notice that an overflow occurred in APK with the loss of a significant digit since the APK field was too short to hold the resulting
sum.
 

          Some unrelated AP’s:


 
 A        DC      P’12345’      = X’12345C’
 B        DC      P’-32’        = X’032D’    
 C        DC      Z’11’         = X’F1C1’
          ...
                           Results:

http://csc.columbusstate.edu/woolbright/ADDPACK.HTM[9/21/2011 4:22:17 PM]


addpack
Contents
          AP    A,=P’20’   A = X’12365C’  C.C. = HIGH
          AP    B,=P’20’   B = X’012D’    C.C. = LOW 
          AP    B,=P’999’  B = X’967C’    C.C. = HIGH  
          AP    A,=P’-100’ A = X’12245C’  C.C. = HIGH
          AP    A,B        A = X’12313C’  C.C. = HIGH
          AP    B,B        B = X’064D’    A FIELD CAN BE ADDED TO ITSELF
                                          C.C. = LOW
          AP    B,=P’32’   B = X’000C’    C.C. = EQUAL
          AP    B,A        B = X’313C’    AN OVERFLOW OCCURS
          AP    A,C                       DATA EXCEPTION - C NOT PACKED
 
 

 
1.  You must be familiar with your data.  The best way to prevent overflows is to plan the size of your fields based on the data at
hand.  There is a rule of thumb that you can follow for additions:  If you are adding two packed fields with m and n bytes, then the
sum might be as large as
max(m, n) + 1 bytes.  You may need to construct a work area to handle the maximum values.  For instance,
                  FIELDA   DS    PL4
                  FIELDB   DS    PL3
                  WORK     DS    PL5
 
In planning to add FIELDA and FIELDB,   we construct a work field called “WORK”.  The following code completes the task.
 
                        ZAP    WORK,FIELDA
                        AP     WORK,FIELDB

http://csc.columbusstate.edu/woolbright/ADDPACK.HTM[9/21/2011 4:22:17 PM]


add register
Contents

                                                             
 
   The Add Register instruction performs 2’s complement binary addition.  Operand 1 is a register containing a fullword integer. 
Operand 2 specifies a register as well.  The fullword in Operand 2 is added to the fullword in Operand 1,  and the sum replaces
the contents of Operand 1.  Operand 2 in unchanged by this operation except when Operand 1 and 2 refer to the same register. 
Consider the following example,    
 
                            AR    R9,R8

               
 
 
   The contents of the fullword in register 8, x’00000479’, are added to the contents of register 9 which contains x’000003FA’ .  The
sum is x’00000873’  and replaces the previous value in R9.  The contents of register 8 are unchanged by this operation.
 
   The condition code is set by this instruction to zero (0) if the result is zero, it is set to minus (1) if the result is negative, and to
plus (2) if the result is positive.
 

            Some Unrelated Add Registers


 
              R4 =  X’FFFFFFFE’   -2 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
  
              AR    R4,R5    R4 = X’00000026’ = +38
              AR    R4,R4    R4 = X’FFFFFFFC’ = -4
              AR    R5,R6    R5 = X’0000002C’ = +44
              AR    R6,R5    R6 = X’0000002C’ = +44

http://csc.columbusstate.edu/woolbright/ADDREG.HTM[9/21/2011 4:22:18 PM]


bas
Contents

                                                    

                                                       
 
   BAS is a RX instruction which is used to support internal subroutines.  When executed, the address of the instruction which
follows the BAS, a return address, is stored in the operand 1 register, and a branch is taken to the address specified by operand
2.  BAS is used in combination with BR to construct internal subroutines (routines that are contained in the same control section). 
Consider the instruction sequence below
 
                     BAS   R8,SUB1
                     BAS   R8,SUB2
                     MVC   X,Y
                     ...
            SUB1     EQU   *         
                     ...             (SUBROUTINE CODE GOES HERE)
                     BR    R8        BRANCH TO THE RETURN ADDRESS
            SUB2     EQU   *
                     ...             (SUBROUTINE CODE GOES HERE)
                     BR    R8        BRANCH TO THE RETURN ADDRESS
 
When the first BAS instruction is executed, the address of the next instruction (BAS R8,SUB2) is loaded into R8.  After this return
address is loaded, a branch occurs to the address denoted by SUB1.  This begins execution of the code in the subroutine.  At
completion of the subroutine, an unconditional branch (BR  R8) occurs to the address in R8.  Execution  resumes at the second
BAS instruction.   The second BAS causes the address of the next instruction (MVC  X,Y) to be loaded into R8.  A branch is taken
to the subroutine denoted by SUB2.  After execution of the subroutine, the unconditional branch (BR  R8) at the end of the
subroutine returns control at the MVC instruction.
 
BAS replaces an older instruction called “BAL” which stands for “Branch and Link”.  Both of these instructions load the address of
the next instruction into operand 1.  The difference in their operation depends on the addressing mode that the machine is using:
 
   In 24 bit mode:     BAL loads bits 0 - 7  of operand 1 with linkage information ( instruction
                                        length code, condition code, program mask )
                               BAL loads bits 8 - 31 of operand 1 with the 24 bit return address
 
                               BAS loads bits 0 - 7 with eight 0’s
                               BAS loads bits 8 - 31 of operand 1 with a 24 bit return address
 
   In 31 bit mode     BAS and BAL load bit 0 with a 1 indicating 31 bit mode addressing
                               BAS and BAL load bits 1 - 31 with a 31 bit return address
The information that was provided by BAL in bits 0 - 7,  can now be obtained using the IPM ( insert Program Mask ) instruction.
 

     Some Unrelated BAS’s


 
      BAS    R4,HERE  LOAD NEXT ADDRESS IN R4, BRANCH TO “HERE”
      BAS    R8,THERE LOAD NEXT ADDRESS IN R8, BRANCH TO “THERE”
      BAS    R10,YON  LOAD NEXT ADDRESS IN R10, BRANCH TO “YON”

1)  Use BAS instead of BAL to avoid non-zero bits being placed in the high-order byte of the stored address.
 
2)  When creating internal subroutines, consider saving the linkage register on entry to the subroutine and restoring it just before
exiting:

http://csc.columbusstate.edu/woolbright/BAS.HTM[9/21/2011 4:22:19 PM]


bas
Contents
 
            SUB1    EQU    *
                    ST     R8,SAVE8      SAVE THE RETURN ADDRESS LOCALLY
                    ...    (SUBROUTINE CODE GOES HERE)
                    L      R8,SAVE8      RESTORE THE RETURN ADDRESS
                    BR     R8
                    DS    0F
            SAVE8   DS     F
 
   By saving and restoring the linkage register, the subroutine is free to call other internal subroutines with the same linkage
register.
 

http://csc.columbusstate.edu/woolbright/BAS.HTM[9/21/2011 4:22:19 PM]


basr
Contents

                                                    

                                                                  
 
   BASR is a RR instruction which is used to support linkage and internal subroutines.  When executed, the address of the
instruction which follows the BASR, a return address, is stored in the operand 1 register, and a branch is taken to the address in
the operand 2 register.  No branch is taken if R0 is specified as operand 2.  In this case, execution continues with the instruction
following the BASR.  Consider the instruction sequence below
 
                     LA    R15,SUB1  PUT TARGET ADDRESS IN R15
                     BASR  R14,R15   SAVE “HERE” AS THE RETURN ADDRESS
            HERE     EQU   *         THE RETURN ADDRESS
                     MVC   X,Y
                     ...
            SUB1     EQU   *
                     ...   (SUBROUTINE CODE GOES HERE)
                     BR    R14     BRANCH TO THE RETURN ADDRESS
 
First the address of the subroutine ( the target address) is loaded into register 15.  When the BASR is executed, the address of
the next instruction (MVC) is loaded into R14.  Recall that the EQU directive does not generate object code, and so the address
denoted by HERE is equivalent to the address of the MVC instruction.  After the return address is loaded, a branch occurs to the
address in R15 (SUB1).  This begins execution of the code in the subroutine.  At completion of the subroutine, an unconditional
branch occurs to the address in R14.  This causes execution to resume at the MVC instruction.
 
   BASR can also be used in the format listed below.
 
                     BASR    R12,R0
 
   In this case, the address of the next instruction is loaded into R12, and no branch is taken since operand 2 was specified as R0. 
This form of a BASR is used in the topic called Base / Displacement Addressing.  Briefly, R12 is declared to be a base register
in a USING  statement and the BASR loads R12 with the base address ( the address of the next instruction ).
 
   BASR replaces an older instruction called “BALR”.  Both of these instructions load the address of the next instruction into
operand 1.  The difference in their operation depends on the addressing mode that the machine is using:
 
   In 24 bit mode:     BALR loads bits 0 - 7  of operand 1 with linkage information ( instruction
                                         length code, condition code, program mask )
                               BALR loads bits 8 - 31 of operand 1 with the 24 bit return address
 
                               BASR loads bits 0 - 7 with eight 0’s
                               BASR loads bits 8 - 31 of operand 1 with a 24 bit return address
 
   In 31 bit mode     BASR and BALR load bit 0 with a 1 indicating 31 bit mode addressing
                               BASR and BALR load bits 1 - 31 with a 31 bit return address
The information that was provided by BALR in bits 0 - 7, can now be obtained using the IPM ( Insert Program Mask ) instruction.
 

     Some Unrelated BASR’s


 
      BASR    R4,R5  LOAD NEXT ADDRESS IN R4, BRANCH TO ADDRESS IN R5
      BASR    R4,R0  LOAD NEXT ADDRESS IN R4, DON’T BRANCH
      BASR    R3,R0  LOAD NEXT ADDRESS IN R3, DON’T BRANCH
 
 

http://csc.columbusstate.edu/woolbright/BASR.HTM[9/21/2011 4:22:20 PM]


basr
Contents

1)  Use BASR instead of BALR to avoid non-zero bits being placed in the high-order byte of the stored address.
 
2)  Read about the use of BASR in the topic Base Displacement Addressing.
 

http://csc.columbusstate.edu/woolbright/BASR.HTM[9/21/2011 4:22:20 PM]


Branch on Condition
Contents

 
 
   The Branch on Condition instruction examines the 2-bit condition code in the PSW and branches (or not) based on the value it
finds.  Operand 1 is a self-defining term which represents a 4-bit mask (binary pattern) indicating the conditions under which the
branch should occur.  Operand 2 is the target address to which the branch will be made if the condition indicated in Operand 1
occurs. If the condition code has one of the values specified in the mask, the instruction address in the PSW is replaced with the
target address in the instruction.  This causes the processor to fetch the instruction located at the target address as the next
instruction in the fetch/execute cycle.  See System 390 Architecture for more details.
 
   There are four possible values for the condition code:
 
                              Condition Code                  Meaning
 
                   00            Zero or Equal
                   01            Low or Minus
                   10            High or Plus
                   11              Overflow
                 
   When constructing a mask for Operand 1, each bit ( moving from the high-order bit to the low-order bit ) represents one of the
four conditions in the following order:  Zero/Equal, Low/Minus, High/Plus, Overflow.  Consider the following instruction,
 
                           BC   8,THERE
 
The first operand,”8”, is a decimal self-defining term and represents the binary mask B’1000’.  Since the first bit is a 1, the mask
indicates that a branch should occur on a zero or equal condition.  Since the other bits are all 0, no branch will be taken on the
other conditions.  The first operand could be designated as any equivalent self-defining term.  For example, the following instruction
is equivalent to the one above.
 
                           BC   B’1000’,THERE
 
   Extended mnemonics were developed to replace the awkward construction of having to code a mask.  The extended mnemonics
are easier to code and read.  A listing of the extended mnemonics follows below.
 
              BE      Branch Equal       BNE      Branch Not Equal
              BZ      Branch Zero        BNZ      Branch Not Zero
              BL      Branch Low         BNL      Branch Not Low
              BM      Branch Minus       BNM      Branch Not Minus
              BH      Branch High        BNH      Branch Not High
              BP      Branch Positive    BNP      Branch Not Positive
              NOP     No Operation       B        Unconditional Branch
 
 
Using extended mnemonics we could replace the previous Branch On Condition instruction with the following,
 
                           BZ   THERE
 
The “BZ” means “Branch on Condition Zero”.  When the assembler processes BZ, it generates the mask as B’1000’.  The table
below indicates the possible mask values and the equivalent extended mnemonics.
 
 Eq/Low   Low/Min   High/Plus   Overflow   Decimal     Extended
                                           Condition   Mnemonic
   0          0          0          0          0          NOP
   0          0          0          1          1          BO
   0          0          1          0          2          BH, BP
   0          0          1          1          3          No mnemonic

http://csc.columbusstate.edu/woolbright/BC.HTM[9/21/2011 4:22:21 PM]


Branch on Condition
Contents
   0          1          0          0          4          BL, BM
   0          1          0          1          5          No mnemonic
   0          1          1          0          6          No mnemonic
   0          1          1          1          7          BNE, BNZ
   1          0          0          0          8          BE, BZ
   1          0          0          1          9          No mnemonic
   1          0          1          0         10          No mnemonic
   1          0          1          1         11          BNL, BNM
   1          1          0          0         12          No mnemonic
   1          1          0          1         13          BNH, BNP
   1          1          1          0         14          No mnemonic
   1          1          1          1         15          B
 

          Some Unrelated Branch on Conditions


 
              LTR  R8,R8     SET THE CONDITION CODE
              BP   THERE     BRANCH IF CONDITION CODE IS POSITIVE 
              ...            OTHERWISE FALL THROUGH TO NEXT INSTRUCTION 
      THERE   EQU  *
 
              CLC  X,Y       SET THE CONDITION CODE
              BE   THERE     BRANCH IF X = Y 
              ...            OTHERWISE FALL THROUGH TO NEXT INSTRUCTION 
      THERE   EQU  *
 
              CLC  X,Y       SET THE CONDITION CODE
              BH   THERE     BRANCH IF X > Y 
              ...            OTHERWISE FALL THROUGH TO NEXT INSTRUCTION 
      THERE   EQU  *

http://csc.columbusstate.edu/woolbright/BC.HTM[9/21/2011 4:22:21 PM]


BCT
Contents

 
 
   BCT is used to implement counted loops - loops in which the number of iterations is known before entrance to the loop body
occurs.  First the number of iterations is loaded into operand 1, a register which will control the loop.  Operand 2 specifies a target
address to branch to when the end of the loop body is encountered.  Each time the BCT is executed the register denoted by
operand 1 is decremented by 1.  (The subtraction occurs in 2’s complement arithmetic.)  If the result in operand 1 is not zero, the
branch is taken to the target address specified in operand 2.  If the result is zero, execution continues with the instruction following
the BCT.  Here is an example.
 
                  LA   R8,3    SET THE NO. OF ITERATIONS TO 3
         LOOP     EQU  *
                  ...  (LOOP BODY GOES HERE)
                  BCT  R8,LOOP  DECREMENT LOOP, BRANCH BACK IF NOT ZERO
 
   In the example above, 3 is loaded into R8.  The loop body is executed and the BCT is executed. This causes R8 to be
decremented by 1.  Since the result, 2, is not zero, a branch occurs back to “LOOP”.  The loop body is executed again, and BCT
reduces R8 to 1.  Again, a branch is taken to “LOOP”.  The loop body is executed a third time and R8 is reduced to 0 by the
execution of BCT.  Since the result in R8 is equal to zero, the branch is not taken and execution continues with the instruction
which follows the BCT.                          
 
 

          Some Unrelated BCTs


 
              R4 =  X’00000004’
              R5 =  X’00000001’
              R6 =  X’00000000’    
  
       BCT   R4,HERE   R4 = X’00000003’, BRANCH IS TAKEN TO “HERE”
       BCT   R5,THERE  R5 = X’00000000’, NO BRANCH IS TAKEN
       BCT   R6,YON    R6 = X’FFFFFFFF’,(-1 IN 2’S COMPLEMENT),
                                         BRANCH IS TAKEN TO “YON” 

1.  Be sure to initialize the register that controls the loop.  In the last example above, the loop would execute the loop body 2 31
times, running through all possible values, before R6 contained a 0.

http://csc.columbusstate.edu/woolbright/BCT.HTM[9/21/2011 4:22:22 PM]


basr
Contents

                                                    

                                                                  
 
   BCTR is the RR version of BCT.  It is used to support counted loops - loops in which the number of iterations is known before
entry to the loop body.  Operand 1 is a register which contains a count - the number of iterations the loop should perform.  Each
time the BCTR is executed, the operand 1 register is decremented by 1.  If the result is not zero, a branch is taken to the address
stored in the register denoted by operand 2.  If the result is zero, no branch is taken and execution continues with the instruction
following the BCTR.  Here is an example of how BCTR can be used to create a counted loop.
 
                     LA    R10,LOOP  PUT TARGET ADDRESS IN R10
                     LA    R8,3      LOOP 3 TIMES
            LOOP     EQU   *
                     ... (LOOP BODY GOES HERE)
                     BCTR  R8,R10    BRANCH TO “LOOP” IF NOT ZERO
                     MVC   X,Y
 
First the address of the loop body ( the target address) is loaded into register 10.  Then the number of iterations, 3, is put in R8. 
The loop body is executed.  The BCTR decrements R8 to 2, and since the result is not zero, a branch is taken to the address in
R10  which is LOOP.  The loop body is executed again and the BCTR decrements R8 to 1.  Since the result was not zero, a
branch is taken to LOOP.  The third execution of the loop body occurs and BCTR decrements R8 to 0.  No branch is taken in this
case, and execution falls through the loop and continues with the MVC instruction.
 
   BCTR is sometimes coded with R0 specified in operand 2 to indicate that no branch should be taken.  Execution continues with
the next instruction.
 
                       BCTR   R5,R0
 
   In this case, R5 is decremented by 1.  Since R0 was coded as the second operand, execution continues with the instruction
following the branch.  Coding BCTR in this way provides an easy and efficient way to subtract 1 from a register.
 

     Some Unrelated BCTR’s


 
              R4 = X’00000008’
              R5 = A(HERE)
              R6 = X’00000001’
              R7 = X’00000002’
      BCTR    R4,R5  R4 = X’00000007’, BRANCH TO “HERE”
      BCTR    R4,R0  R4 = X’00000007’, DON’T BRANCH, FALL THROUGH
      BCTR    R6,R5  R6 = X’00000000’, DON’T BRANCH
      BCTR    R7,R5  R7 = X’00000001’, BRANCH TO “HERE”

http://csc.columbusstate.edu/woolbright/BCTR.HTM[9/21/2011 4:22:23 PM]


storage to storage type one
Contents

 
 
   CLC is used to compare two fields that are both in storage.  The fields are compared, one byte at a time beginning with the
bytes specified in addresses B1 D 1 D 1 D 1  and B2 D 2 D 2 D 2 , and moving to higher addresses in the source and target fields.  Each
byte in the source is compared to a byte in the target according to the ordering specified in the EBCDIC encoding sequence. 
Executing a compare instruction sets the condition code (a two bit field in the PSW) to indicate how operand 1 (target field)
compares with operand 2 (source field). The condition code is set as follows,
 
           Comparison                               Condition Code Value                Test With
 
Operand 1 equals Operand 2                            0  (equal)                       BE   (Branch Equal)
                                                                                                               BNE (Branch Not equal)
Operand 1 is less than Operand 2                     1  (low)                          BL    (Branch Low)
                                                                                                               BNL (Branch Not Low)
Operand 1 is greater than Operand 2                2  (high)                         BH   (Branch High)
                                                                                                               BNH (Branch Not High)
 
The table above also indicates the appropriate branch instructions for testing the condition code.  When comparing two fields, a
CLC instruction should be followed immediately by one or more branch instructions for testing the contents of the condition code:
            
             CLC     FIELDA,FIELDB
             BH      AHIGH        BRANCH IF FIELDA IS HIGH
             BL      BHIGH        BRANCH IF FIELDA IS LOW
 
   Bytes are compared until the number of bytes specified (implicitly or explicitly) in operand 1 have been exhausted or until two
unequal bytes are found - whichever occurs first.
As you can see from the instruction format above, the instruction carries with it the maximum number of bytes to be compared, as
well as the beginning addresses of the source and target fields.  Notice that the instruction does not specify the ending addresses
of either field - the instruction is no respecter of fields.  If a longer field is compared to a shorter field, the bytes following the
shorter field may be used in the comparison operation.
 
   The length (LL1 ) determines the maximum number of bytes which will be compared. The length is usually determined implicitly
from the length of operand 1 but the programmer can provide an explicit length.   Consider the two example CLC’s below,
 
 
 
 
 
 
 
     Object code                      Assembler code
 
                FIELDA    DC    CL4’ABCD’
                FIELDB    DC    C’ABE’
                          ...     
  D502C00CC008            CLC   FIELDB,FIELDA     Implicit length = 3,
                                                  COND CODE = HIGH
  D501C00CC008            CLC   FIELDB(2),FIELDA  Explicit length = 2,
                                                  COND CODE = EQUAL
 
   In the first CLC, ‘A’ in FIELDB is compared with ‘A’ in FIELDA, then ‘B’ in FIELDB is compared with ‘B’ in FIELDA, finally, ‘E’ in

http://csc.columbusstate.edu/woolbright/CLC.HTM[9/21/2011 4:22:23 PM]


storage to storage type one
Contents
FIELDB is compared with ‘C’ in FIELDA.  At this point, the condition code is set to ‘HIGH’ since ‘E’ follows ‘C’ in the EBCDIC
encoding sequence.  In the second example, ‘A’ in FIELDB is compared with ‘A’ in FIELDA, then ‘B’ in FIELDB is compared with
‘B’ in FIELDA.  The condition code is set to ‘EQUAL’ since an explicit length of 2 was coded.
 

          Some Unrelated CLC’s:


 
   A        DC    C’PQR’
   B        DC    C’ABCD’    
   C        DC    C’PQ’
   D        DC    P’12’      D = X’012C’
            ...           Result:
            CLC   A,B     Condition Code = High, one byte compared.
            CLC   A(2),C  Condition Code = Equal, two bytes compared.
            CLC   C,A     Condition Code = Equal, two bytes compared.
            CLC   A,=C’ ’ Condition Code = High, one byte compared. This
                          coding is unwise since it sets up the
                          possibility that bytes following the blank
                          literal in the literal pool might become part
                          of the comparison.
            CLC   A,=CL3’ ’  Condition Code = High, this is a better
                          version of the previous comparison.  Should
                          length of “A” change, an error may occur.
            CLC   B,=X’C1C2C3C4’  Condition Code = Equal,
                           4 bytes were compared.
            CLC   D,=P’12’ This is a dangerous compare since the data
                           involved is in packed format.  If the
                           fields are unchanged from their assembly
                           time format the condition code would be
                           equal.
            CLC   A(500),B  Assembly Error -  max  length is 256
            CLC   A,B(20)   Assembly Error -  operand 1 determines the
                            length

 
1. As with any storage to storage instruction, you must pay careful attention to lengths of the two operands.  Generally, you should
be comparing fields that are the same size.
 
2.  The instruction was designed to compare fields that are in character format.  It can be used to compare fields with non-
character data, but this takes special consideration to make sure the comparison will produce the desired results.  Packed decimal
data and binary data are supported with their own special comparison instructions.
 
3.  The condition code can be changed by any other type of comparison instruction as well as by a variety of arithmetic
instructions.  Don’t rely on the condition code to remain set -  after you have issued a CLC , you should follow it up immediately
with a branch instruction.

http://csc.columbusstate.edu/woolbright/CLC.HTM[9/21/2011 4:22:23 PM]


CLI
Contents

 
 
   CLI is used to compare two fields that are both in storage.  Operand 1 is a field in main storage, while the second operand is a
self-defining term that gets assembled as a one byte immediate constant (II 2 ) in the second byte of the object code of the CLI
instruction.  Only the first byte of Operand 1 is compared to the immediate constant.  The comparison is made based on the
ordering of characters in the EBCDIC encoding. 
 
   Executing a compare instruction sets the condition code (a two bit field in the PSW) to indicate how operand 1 (target field)
compares with operand 2 (immediate constant). The condition code is set as follows,
 
           Comparison                               Condition Code Value                Test With
 
Operand 1 equals Operand 2                            0  (equal)                       BE   (Branch Equal)
                                                                                                               BNE (Branch Not equal)
Operand 1 is less than Operand 2                     1  (low)                          BL    (Branch Low)
                                                                                                               BNL (Branch Not Low)
Operand 1 is greater than Operand 2                2  (high)                         BH   (Branch High)
                                                                                                               BNH (Branch Not High)
 
The table above also illustrates the appropriate branch instructions for testing the condition code.  When comparing two fields, a
CLI instruction should be followed immediately by one or more branch instructions for testing the contents of the condition code:
            
    FIELDA   DC      C’1234’
             ...
             CLI     FIELDA,C’A’
             BH      AHIGH        BRANCH IF FIELDA IS HIGH
             BL      BHIGH        BRANCH IF FIELDA IS LOW
 
 In the example above, the first byte of FIELDA, which contains the character  “1” and is represented as x’F1’, is compared to the
self-defining term C’A’, which assembles as a x’C1’.  In EBCDIC, since x’F1’ is greater than x’C1’, the condition code is set to
“high” to indicate that operand 1 is “higher” than operand 2.
 
   The following example illustrates how a CLI might be processed by the assembler.
 
     LOC      OBJECT CODE
 
 000F12  95F4C044                   CLI    CUSTCODE,C’4’  
                                    ...
 001028                CUSTCODE     DS    CL1
 
In the example above, the op-code for CLI is x’95’,  the self-defining term C’4’ is assembled as the one byte hexadecimal constant
x’F4’, and CUSTCODE is translated into the base/displacement address C044.
 
 

          Some Unrelated CLI’s:


 
   J        DC    C’ABC’
   K        DC    C’DEF’    

http://csc.columbusstate.edu/woolbright/CLI.HTM[9/21/2011 4:22:24 PM]


CLI
Contents
   L        DC    C’GH’
   M        DC    C’12345’   
                          Result:
            CLI   J,C’A’  Condition Code = Equal, one byte compared.
            CLI   J,C’B’  Condition Code = Low.
            CLI   J,C’5’  Condition Code = Low, letters < numbers.
            CLI   K,X’C4’ Condition Code = Equal.
            CLI   L,C’A’  Condition Code = High.
            CLI   L,=C’G’ Assembly error, Literals not allowed.
            CLI   B,X’C1C2’ Assembly error, 1-byte comparisons only.
            CLI   C’A’,M  Assembly error, operands out of order.
            CLI   A(20),B Assembly Error, 1-byte comparisons only.
            CLC   A,B(20)   Assembly Error -  operand 1 determines the
                            length

 
1.  Use CLI instead of CLC when comparing 1-byte fields.  The resulting code is smaller and slightly more efficient.  More
importantly, it makes explicit the fact that you are comparing two 1-byte fields. 

http://csc.columbusstate.edu/woolbright/CLI.HTM[9/21/2011 4:22:24 PM]


Compare Halfword
Contents

 
 
   The Compare Halfword instruction is used to compare a binary fullword in a register, Operand 1, with a binary halfword in
memory, Operand 2.  The operands are compared as 2’s complement signed binary integers.  For purposes of comparison, the
halfword is “sign-extended” to a fullword before the comparison occurs.  This extension occurs internally and is temporary.  The
instruction sets the condition code to indicate how Operand 1 compares to Operand 2:
                              
                      Condition Code               Meaning                            Test With
 
                                0                    Operand 1 = Operand 2                 BE, BZ
                                1                    Operand 1 < Operand 2                 BL, BM
                                2                    Operand 1 > Operand 2                 BH, BP
                             
 
                            CH    R9,AFIELD       
 

 
   The contents of the halfword “AFIELD”, x012C’, is signed extended to a fullword, x’0000012C’, and is compared to the contents
of register 9 which contains x’000045FF’.  Since the contents of the register (Operand 1) is greater than the value than the
extended halfword (Operand 2), the condition code is set to “High”.  The condition code in the diagram above is specified using 2
binary digits.  After comparison, the condition code is set to a binary 10 which is 2 in decimal - a “High” condition.
 
   Since CH is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 
 
 
 
 
 

        Some Unrelated Compare Halfwords


 
              R4 =  X’FFFFFFD5’  -43 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT

http://csc.columbusstate.edu/woolbright/COMPHALF.HTM[9/21/2011 4:22:25 PM]


Compare Halfword
Contents
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
  
              DOG   DC   H’40’
              CAT   DC   H’-30’
              PIG   DC   H’14’
              GOAT  DC   H’3’
 
              CH    R4,=H’20’    CONDITION CODE = LOW
              CH    R4,=H’-50’   CONDITION CODE = HIGH
              CH    R5,=H’20’    CONDITION CODE = HIGH
              CH    R6,=H’4’     CONDITION CODE = EQUAL
              CH    R5,=H’40’    CONDITION CODE = EQUAL
              CH    R5,DOG       CONDITION CODE = EQUAL
              CH    R6,DOG(R6)   CONDITION CODE = LOW
                                 DOG(R6) IS EQUIVALENT TO PIG

http://csc.columbusstate.edu/woolbright/COMPHALF.HTM[9/21/2011 4:22:25 PM]


compare pack
Contents

 
   CP is a SS 2 instruction which is used to compare packed decimal fields.  This instruction sets the condition code to “equal”
(condition code = 0), “low” (condition code = 1) or “high” (condition code = 2) based on a comparison of the two fields as decimal
numbers, and indicates how the first operand compares to the second operand.  The fields may be of equal or different sizes.  The
only restrictions on the field lengths is that they must be a maximum of 16 bytes in length (the typical restriction for SS 2 fields). 
Consider the fields and instructions below.
 
                   APK      DC     P’123’ = X’123C’
                  BPK      DC     PL3’100’ = X’00100C
                  CHX      DC     X’123F’
                           ...
                           CP     APK,BPK     C.C.= HIGH
                           CP     APK,CHX     C.C.= EQUAL
                           CLC    APK,CHX     C.C.= LOW
 
 In the first CP, the fields are compared arithmetically and it is found that +123 is greater than +100.  In the second compare,  the
condition code is set to “equal”  since  +123 is equal to +123 (x’F’ is a valid plus sign).  The third compare is a logical compare
rather than an arithmetic compare.  Since x’3C’ is lower than x’3F’ in the EBCDIC collating sequence, the condition code is set to
“low”.
 
  After setting the condition code with a CP, the condition code can be tested with a branch instruction.  The typical branch
instructions you might use are BE or BNE, BL or BNL, and BH or BNH.
 
  

          Some unrelated CP’s:


 
 QPK      DC      P’12345’      = X’12345C’
 RPK      DC      P’-32’        = X’032D’    
 SZONED   DC      Z’11’         = X’F1C1’
          ...
                           Results:
          CP    QPK,=P’20’   C.C. = HIGH
          CP    RPK,=P’20’   C.C. = LOW 
          CP    SZONED,=P’999’  ABEND - SZONED IS NOT PACKED  
          CP    QPK,QPK      C.C. = EQUAL
          CP    QPK,RPK      C.C. = HIGH
          CP    RPK,QPK      C.C. = LOW
          CP    QPK,=X’324A’ C.C. = HIGH  - LITERAL IS VALID PACKED DATA
          CP    QPK+2(1),RPK   BAD IDEA, BUT IT DOES WORK C.C. = HIGH,

http://csc.columbusstate.edu/woolbright/COMPPACK.HTM[9/21/2011 4:22:26 PM]


Compare Registers
Contents

 
 
   The Compare Register instruction is used to compare a binary fullword in a register, designated by Operand 1, with another
fullword in a register, designated by Operand 2.  The operands are compared as 32-bit signed binary integers.  The instruction sets
the condition code to indicate how Operand 1 compares to Operand 2:
                              
                      Condition Code               Meaning                            Test With
 
                                0                    Operand 1 = Operand 2                 BE, BZ
                                1                    Operand 1 < Operand 2                 BL, BM
                                2                    Operand 1 > Operand 2                 BH, BP
                             
   The following example sets the condition code by comparing registers 9 and 6.
 
                            CR    R9,R6       
 

     
 
   The contents of the fullword in register 9, x’FFFFFFFF’ = -1, is compared to the contents of register 6 which contains
x’000001AF’ = 431.  Since the contents of the Operand 1 register is less than the contents of the Operand 2 register, the condition
code is set to “Low”.  The condition code in the diagram above is specified using 2 binary digits.  After comparison, the condition
code is set to a binary 01 which is 1 in decimal - a “Low” condition.
 
 
 
 
 
 

          Some Unrelated Compare Registers


 
              R4 =  X’FFFFFFD5’  -43 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
 
              CR    R4,R5    CONDITION CODE = LOW

http://csc.columbusstate.edu/woolbright/COMPREG.HTM[9/21/2011 4:22:27 PM]


Compare Registers
Contents
              CR    R5,R4    CONDITION CODE = HIGH
              CR    R4,R4    CONDITION CODE = EQUAL
              CR    R6,R5    CONDITION CODE = LOW
              CR    R5,R5    CONDITION CODE = EQUAL

http://csc.columbusstate.edu/woolbright/COMPREG.HTM[9/21/2011 4:22:27 PM]


SUBTRACT
Contents

 
 
   The Compare instruction is used to compare a binary fullword in a register, Operand 1, with a fullword in memory, Operand 2. 
The operands are compared as 32-bit signed binary integers.  The instruction sets the condition code to indicate how Operand 1
compares to Operand 2:
                              
                      Condition Code               Meaning                            Test With
 
                                0                    Operand 1 = Operand 2                 BE, BZ
                                1                    Operand 1 < Operand 2                 BL, BM
                                2                    Operand 1 > Operand 2                 BH, BP
                             
 
                            C    R9,AFIELD       
 

   The contents of the fullword “AFIELD”, x’00000020’, is compared to the contents of register 9 which contains x’000000FF’.  Since
the contents of the register (Operand 1) is greater than the value than the fullword in memory (Operand 2), the condition code is
set to “High”.  The condition code in the diagram above is specified using 2 binary digits.  After comparison, the condition code is
set to a binary 10 which is 2 in decimal - a “High” condition.
 
   Since C is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 
 
 
 
 

          Some Unrelated Compares


 
              R4 =  X’FFFFFFD5’  -43 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
  
              DOG   DC   F’35’
              CAT   DC   F’4’

http://csc.columbusstate.edu/woolbright/COMP.HTM[9/21/2011 4:22:28 PM]


SUBTRACT
Contents
 
              C    R4,=F’20’    CONDITION CODE = LOW
              C    R5,=F’-20’   CONDITION CODE = HIGH
              C    R6,=F’20’    CONDITION CODE = LOW
              C    R6,=F’4’     CONDITION CODE = EQUAL
              C    R5,=F’40’    CONDITION CODE = EQUAL
              C    R5,DOG       CONDITION CODE = HIGH
              C    R6,DOG(R6)   CONDITION CODE = EQUAL

http://csc.columbusstate.edu/woolbright/COMP.HTM[9/21/2011 4:22:28 PM]


cvb
Contents

 
 
   The Convert to Binary instruction takes packed decimal data and converts it to 2’s complement  integer data.  Operand 1
designates a register where the result will be stored.  Operand 2 represents a doubleword storage area which contains a valid 8-
byte packed decimal integer.
 
   CVB can convert any signed packed decimal integer in the range -2,147,483,648 and +2,147,483,647.  If the doubleword
specified in Operand 2 contains an integer outside this range, the 32 rightmost bits of the result are placed in the Operand 1
register and a fixed-point-divide exception is recognized.
 
   In the following example, a packed field of length 4 is converted to binary.
 
                     ZAP   DOUBWORD,XPACK   MOVE PACKED NO TO DOUBLEWORD
                     CVB   R5,DOUBWORD      CHANGE IT TO BINARY
                     ...
            XPACK    DC    PL4’123’         X’0000123C’
            DOUBWORD DS    D
 
   To convert XPACK to binary, we must first move it to a doubleword as required by the CVB instruction.  At the end of the
conversion, R5 contains x’0000007B’ = 123.
 
   The diagram below illustrates the relationship between CVB and other data conversion instructions for some common data types.
 

                  
 
 
 
              

          Some Unrelated CVB Instructions


 
     DOUBWORD   DS    D
     PKD1       DC    PL5’19’
     PKD2       DC    P’1865’
     PKD3       DC    P’-1’
 
                ZAP   DOUBWORD,PKD1   MOVE PACKED NO. TO STAGING AREA

http://csc.columbusstate.edu/woolbright/CVB.HTM[9/21/2011 4:22:29 PM]


cvb
Contents
                CVB   R8,DOUBWORD     R8 = X’00000013’ = 19
 
                ZAP   DOUBWORD,PKD2   MOVE PACKED NO. TO STAGING AREA
                CVB   R8,DOUBWORD     R8 = X’00000749’ = 1865
 
                ZAP   DOUBWORD,PKD3   MOVE PACKED NO. TO STAGING AREA
                CVB   R5,DOUBWORD     R5 = X’FFFFFFFF’ = -1
 
                ZAP   DOUBWORD,=C’123’ DATA IS NOT PACKED
                CVB   R4,DOUBWORD      ABEND - DATA MUST BE PACKED
 
                ZAP   DOUBWORD,=P’3,000,000,000’ DATA IS PACKED
                CVB   R4,DOUBWORD    ABEND - FIXED PT. DIVIDE EXCEPTION
                                     DATA > 2,147,483,647

http://csc.columbusstate.edu/woolbright/CVB.HTM[9/21/2011 4:22:29 PM]


CVD
Contents

 
 
   The Convert to Decimal instruction takes a 2’s complement integer from a register and converts it to packed decimal data in
memory.  Operand 1 designates a register containing the 2’s complement integer.  Operand 2 represents a doubleword storage
area in memory where the packed decimal data will be placed.
 
   CVD can convert any 2’s complement integer which is contained in a register.  This includes all integers in the range -
2,147,483,648 and +2,147,483,647.  Since the result is placed in an 8 byte field (doubleword), no overflow can occur since there is
ample room in Operand 2.
 
   In the following example, register 5 is converted to packed decimal and placed in a doubleword. The result can be moved to a
smaller field if the programmer is sure it will fit.
 
                     CVD   R5,DOUBWORD      CHANGE IT TO PACKED DECIMAL
                     ZAP   XPACK,DOUBWORD   DATA WILL FIT IN 10 BYTES
                     ...
            XPACK    DS    PL10
            DOUBWORD DS    D
 
   First the integer in register 5 is converted to packed decimal and placed in a doubleword in memory.  Since the doubleword
contains at most 10 decimal digits ( it was converted from a single register ), it can be transferred to XPACK with ZAP.
 
   The diagram below illustrates the relationship between CVD and other data conversion instructions for some common data types.
 

                  
 
 
 
              

          Some Unrelated CVD Instructions


 
     R7  = X’00000000’ =  0
     R8  = X’0000001F’ = 31
     R9  = X’FFFFFFFF’ = -1
     R10 = X’00001000’ = 4096      

http://csc.columbusstate.edu/woolbright/CVD.HTM[9/21/2011 4:22:30 PM]


CVD
Contents
 
     DOUBWORD  DS    D
                         
               CVD   R7,DOUBWORD   DOUBWORD = X’000000000000000C’
 
               CVD   R8,DOUBWORD   DOUBWORD = X’000000000000031C’
 
               CVD   R9,DOUBWORD   DOUBWORD = X’000000000000001D’
 
               CVD   R10,DOUBWORD  DOUBWORD = X’000000000004096C’

http://csc.columbusstate.edu/woolbright/CVD.HTM[9/21/2011 4:22:30 PM]


divide
Contents

 
 
   The Divide instruction performs 2’s complement binary integer division and returns a quotient and a remainder.  Operand 1
names an even register of an “even-odd” consecutive register pair.  For instance, R2 would be used to name the R2 / R3 even-
odd register pair, and R8 would be used to name the R8 / R9 even-odd register pair.  Operand 2 is the name of a fullword in
memory containing the divisor.  Before the division,  the even-odd register pair must be initialized with the dividend, which is
effectively a 64-bit 2’s complement integer.  After the division, the remainder is contained in the even register and the quotient is
contained in the odd register.  The sign of the quotient is determined by the rules of algebra.  The sign of the remainder will be the
same as the dividend.

                   
 
   In preparing to divide a fullword, a common practice is to load the fullword in the even register and algebraically shift it to the odd
register.  This practice propagates the appropriate sign bit throughout the even register and successfully initialized the even/odd
register pair.  Here is an example where we compute A/B where A and B are fullwords.
 
 
                 L    R8,A      PUT THE DIVIDEND IN THE EVEN REGISTER
                 SRDA R8,32     ALGEBRAICALLY SHIFT R8 INTO R9
                 D    R8,B      DIVIDE A BY B  
                 ...
            A    DC   F’19’     DIVIDEND
            B    DC   F’5’      DIVISOR
 
 
 
 
 
 
 
 
 
 
  The diagram below illustrates the above division just after R8 has been shifted.

http://csc.columbusstate.edu/woolbright/DIVIDE.HTM[9/21/2011 4:22:31 PM]


divide
Contents

        
 
The diagram illustrates that the result of the integer division of 19 by 5 is a remainder of 4 in R8, and a quotient of 3 in R9.
 

          Some Unrelated Divide Instructions


 
       L    R6,=F’100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       D    R6,=F’10’    ... BEFORE DIVIDING
                         R6 (REMAINDER) = X’00000000’,
                         R7 (QUOTIENT) = X’0000000A’
 
       L    R6,=F’100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       D    R6,=F’8’     ... BEFORE DIVIDING
                         R6 (REMAINDER) = X’00000004’,
                         R7 (QUOTIENT) = X’0000000C’
 
       L    R6,=F’100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       D    R6,=F’0’     ... BEFORE DIVIDING
                         ABEND - DIVISION BY 0 NOT ALLOWED
 
       L    R6,=F’-100’  DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       D    R6,=F’-8’     ... BEFORE DIVIDING
                         R6 (REMAINDER) = X’FFFFFFFC’ = -4
                         R7 (QUOTIENT)  = X’0000000C’
 

 
1)  Know your data!  If the divisor might be zero, you must protect your divisions by testing the divisor beforehand.
 
                       CLC   DIVISOR,=F’0    IS THE DIVISOR 0?
                       BE    ZERODIV         BRANCH IF DIVISOR IS 0
                       D     R8,DIVISOR      O.K. TO DIVIDE NOW
                       ...
              ZERODIV  EQU   *
                       (CODE TO HANDLE A ZERO DIVISOR)

http://csc.columbusstate.edu/woolbright/DIVIDE.HTM[9/21/2011 4:22:31 PM]


divide packed
Contents

 
   DP is a SS 2 instruction which is used to divide two packed decimal fields and produce a quotient and a remainder.  Since
packed decimal fields are integers, the division that occurrs is an integer division.  If you are interested in producing a quotient with
decimals, you may need to  use SRP to shift the quotient before the division, and ED to provide a decimal point in the output.  (See
the topic on “Decimal Precision”.)
 
   Operand 1 is a field containing a packed decimal number which is the dividend.  Both the quotient and the remainder develop in
this field.  Operand 2 is a packed decimal field containing the divisor.  The maximum length of the dividend is 16 bytes, and the
maximum length of the divisor is 8 bytes.  Keep in mind the following rules when thinking about the sizes of the generated quotient
and remainder,
 
 1)  The remainder size is equal to the size of the divisor.
 
 2)  The quotient occupies the portion of operand 1 that is not occupied by the remainder.
 
The rules make practical sense when you think about the division process.  Suppose you divide an m-byte divisor into an n-byte
dividend.  Without knowing the specific values, we can see that in an integer division, the remainder might be as large as m bytes,
and the quotient might be as large as n-bytes.  This observation leads to the following rule of thumb for creating work fields in
which to perform the calculation,
 
 
   If the dividend is an n-byte field, and the divisor is an m-byte field, make the work field for the computation at least n+m
bytes.
 
 
Following this rule of thumb will insure that the dividend contains a sufficient number of bytes of leading zeroes before the
computation.  Specifically, the number of bytes of leading zeroes in the dividend must be at least large as the number of bytes in
the divisor.  Here is a sample computation where we want to divide APK by BPK.  Since APK is 3 bytes and BPK is 2 bytes, we
create a work area called “WORK” which is 5 bytes.  This will provide the required number of bytes of leading 0’s for our
computation.
 
 

 
 
 
   DP does not set the condition code.

http://csc.columbusstate.edu/woolbright/DIVPACK.HTM[9/21/2011 4:22:32 PM]


divide packed
Contents
 
 
 

          Some unrelated DP’s:


 
 
 LPK      DC      PL4’100’      = X’0000100C’
 MPK      DC      PL3’6’        = X’00006C’
 NPK      DC      PL2’6’        = X’006C’    
 OZONE    DC      Z’11’         = X’F1C1’
 WORK1    DS     0CL7
 QUOT1    DS      PL4
 REM1     DS      PL3
 WORK2    DS     0CL7
 QUOT2    DS      PL5
 REM2     DS      PL2
          ...
 
                           Results:
          ZAP   WORK1,LPK   WORK = X’0000000000100C’
          DP    WORK1,MPK   WORK = X’0000016C00004C’  QUOT1=16, REM1=4
 
                                                      LENGTH OF REM1=3
          ZAP   WORK2,LPK   WORK = X’0000000000100C’
          DP    WORK2,NPK   WORK = X’000000016C004C’  QUOT1=16, REM1=4
 
                                                      LENGTH OF REM2=2
          ZAP   WORK1,LPK   WORK = X’0000000000100C’
          DP    WORK1,OZONE  ABEND - OZONE NOT PACKED
 
 
          ZAP   WORK1,=P’1234567890’  WORK = X’0001234567890C’
          DP    WORK,MPK       ABEND - NOT ENOUGH BYTES OF LEADING 0’S
                               IN WORK1 - NEEDS 3 BYTES
 
 
 
 
 

 
1.  Don’t divide by zero.  An attempt to divide by zero causes an “0CB” abend.  Protect your divisions by testing the divisor before
you divide.
 
                    ZAP    BPK,BPK      IS DIVISOR 0?
                    BZ     ZERODIV      BRANCH IF ZERO
                    ZAP    WORK,APK     OTHERWISE...
                    DP     WORK,BPK     ... WE CAN DIVIDE
                    ...
           ZERODIV  EQU    *
                    (CODE TO HANDLE A ZERO DIVISOR)

http://csc.columbusstate.edu/woolbright/DIVPACK.HTM[9/21/2011 4:22:32 PM]


divide register
Contents

 
 
   The Divide Register instruction performs 2’s complement binary integer division and returns a quotient and a remainder. 
Operand 1 names an even register of an “even-odd” consecutive register pair.  For instance, R2 would be used to name the R2 /
R3 even-odd register pair, and R8 would be used to name the R8 / R9 even-odd register pair.  Operand 2 names a register that
contains the divisor.  Before the division,  the even-odd register pair must be initialized with the dividend, which is effectively a 64-
bit 2’s complement integer.  After the division, the remainder is contained in the even register and the quotient is contained in the
odd register.  The sign of the quotient is determined by the laws of algebra, and the sign of the remainder is the same as the sign
of the dividend.

                   
 
   In preparing to divide a fullword, a common practice is to load the fullword in the even register and algebraically shift it to the odd
register using SRDA.  This practice propagates the appropriate sign bit throughout the even register. (If the dividend is positive, the
even register is populated with binary 0’s.  If the dividend is negative, the even register is populated with binary 1’s.)  Here is an
example where we compute A/B where A and B are fullwords.
 
                 L    R8,A      PUT THE DIVIDEND IN THE EVEN REGISTER
                 SRDA R8,32     ALGEBRAICALLY SHIFT R8 INTO R9
                 L    R5,B      PUT THE DIVISOR IN R5
                 DR   R8,R5     DIVIDE A BY B  
                 ...
            A    DC   F’19’     DIVIDEND
            B    DC   F’5’      DIVISOR
 
 
 
 
 
 
 
 
 
 
 
   The diagram below illustrates the above division just after R8 has been shifted.

http://csc.columbusstate.edu/woolbright/DIVREG.HTM[9/21/2011 4:22:33 PM]


divide register
Contents

        
 
The diagram illustrates that the results of the integer division of 19 by 5 is a remainder of 4 in R8, and a quotient of 3 in R9.
 
 
              

          Some Unrelated Divide Register Instructions


 
       L    R6,=F’100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       L    R9,=F’10’    DIVISOR GOES IN R9
       DR   R6,R9        ... BEFORE DIVIDING
                         R6 (REMAINDER) = X’00000000’,
                         R7 (QUOTIENT)  = X’0000000A’
 
       L    R6,=F’100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       L    R4,=F’8’     DIVISOR GOES IN R4
       DR   R6,R4        ... BEFORE DIVIDING
                         R6 (REMAINDER) = X’00000004’,
                         R7 (QUOTIENT)  = X’0000000C’
 
       L    R6,=F’100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       SR   R5,R5        ZERO OUT R5
       DR   R6,R5        ... BEFORE DIVIDING
                         ABEND - DIVISION BY 0 NOT ALLOWED
 
       L    R6,=F’-100’   DIVIDEND INITIALLY GOES IN THE EVEN REGISTER
       SRDA R6,32        ... AND IS SHIFTED TO THE ODD REGISTER
       L    R10,=F’-8’    DIVISOR GOES IN R8
       DR   R6,R10       ... BEFORE DIVIDING
                         R6 (REMAINDER) = X’FFFFFFFC’,
                         R7 (QUOTIENT)  = X’0000000C’
 
 
 
 
 

 
1)  Know your data!  If the divisor might be zero, you must protect your divisions by testing the divisor beforehand.
 
                       LTR   R5,R5           ASSUME DIVISOR IS IN R5
                       BZ    ZERODIV         BRANCH IF DIVISOR IS 0
                       DR    R8,R5           O.K. TO DIVIDE NOW
                       ...
              ZERODIV  EQU   *
                       (CODE TO HANDLE A ZERO DIVISOR)
 
2)  Unlike the MR instruction, you must initialize the even register.  The even/odd register pair must contain a 64 bit binary integer
before you execute the instruction.

http://csc.columbusstate.edu/woolbright/DIVREG.HTM[9/21/2011 4:22:33 PM]


edit
Contents

 
   Packed decimal fields can be converted to a character format using the ED instruction.  Additionally, editing symbols and features
like commas, decimal points, and leading zero suppression can be included in the character version of the packed decimal field that
is being edited.  The first step in editing a packed decimal field is to create an “edit word” which is a pattern of what the character
output of the edit process should look like.  Typically, the edit word is moved to a field in the output buffer which is being built,
prior to printing.  Then the packed decimal field is “edited” into the output field, destroying the copy of the edit word.
 
  First, we consider how to construct an appropriate edit word for a given packed decimal field.  This can be accomplished by
defining a string of hexadecimal bytes that represents the edit word.  Each byte in the edit word corresponds to a byte in the edited
character representation.  In creating the edit word there are a collection of standard symbols which are used to describe each
byte:
          X’40’        This symbol, which represents a space, is usually coded as the first byte of the
                          edit word where it acts as a “fill character”.  The fill character is used to replace
                          leading zeroes which are not “significant”.
 
          X’20’        Called a “digit selector”, this byte represents a position in which a
                          significant digit from the packed field should be placed.
  
          X’21’        This hexadecimal byte represents a digit selector and a significance starter. 
                          Significance starts when the first non-zero digit is selected.  Alternatively, we
                          can force significance to start by coding a single x’21’ in the edit word.  In this
                          case, significance starts in the byte following the x’21’.  Significance is
                          important because every significant digit is printed, even if it is a leading zero.
 
          X’6B’        This is the EBCDIC code for a comma. 
 
          X’4B’        This is the EBCDIC code for a decimal point.
 
          X’60’        This is the EBCDIC code for a minus sign.  This symbol is sometimes coded on
                          the end of an edit word when editing signed fields.  The  x’60’ byte will be
                          replaced with the fill character if the number being edited is positive.  If the
                          number is in fact negative, the x’60’ will not be “filled”, and the negative sign will
                          appear in the edited output.
 
          X’C4C2’   The EBCDIC version of “DB” (Debit).  This functions like the x’60’.  Coding
                          these symbols at the end of an edit word causes “DB” to appear in the output
                          if the field being edited is negative, otherewise the “DB” is “filled”.
 
          X’C3D9’   The EBCDIC version of “CR” (Credit).  This functions like the Debit symbol
                          above.  When the number being edited is negative, the “CR” symbol will
                          appear in the edited output, otherwise it will be “filled”.
          X’5C’        The EBCDIC symbol for an asterisk.  This character is sometimes used as
                          a fill character when editing dollar amounts on checks.
             
   We now consider a sample edit word and the output it would create for several packed fields.
 
                    EDWD     DC    X’4020206B2021204B202060’
                    AOUT     DC    CL11
                    APK      DC    PL4’45387’  

http://csc.columbusstate.edu/woolbright/ED.HTM[9/21/2011 4:22:34 PM]


edit
Contents
 
Assume we execute the instructions below,
 
                    MVC      AOUT,EDWD
                    ED       AOUT,APK
 
First, the edit word is moved to a field in the output buffer.  Then the packed field is “edited” into the output field.   The results are
illustrated in the diagram below.
 

        
 
The diagram indicates the results of the edit process:  The fill character (x’40’) is unaffected, and is left in its position.  The first
decimal digit, 0, is “selected” by the first x’20’, and since leading 0’s are not significant, the x’20’ is replaced by the fill character. 
The second digit, 0, is also selected, and it too, is filled with a x’40’.  Since significance has not started, the x’6B’ is filled with
x’40’.  The first non-zero digit, 4, is selected and this signals that significance has started.  (Any non-zero digit which is selected
turns on the significance indicator.)  Each digit after the 4 will appear in the edited result.  The “4” is replaced with its character
equivalent - x’F4’.  The “5” is selected and its x’20’ is replaced with x’F5’.  The “3” is selected and is represented as x’F3’.  The
x’4B’, a decimal point, remains unaffected.  The “8” is selected and is represented as x’F8’.  The “7” is selected and is represented
as x’F7’.  Since the number being edited is positive, the x’60’ is filled with x’40’.   The final result would print as “    453.87 “. 
 
 
   Consider a second edit which uses the same edit word as in the previous example, but with a different value for APK.
 
                    EDWD     DC    X’4020206B2021204B202060’
                    AOUT     DC    CL11
                    APK      DC    PL4’-7’  
 
Again we execute the same sequence of instructions.
 
                    MVC      AOUT,EDWD
                    ED       AOUT,APK
 

 
As in every edit, the x’40’ fill character is unaffected by the edit process.  The first and second digits, both 0, are selected, and
since they are leading 0’s and significance has not started, they are filled with x’40’.  The x’6B’ is also filled with x’40’ since
significance has not started.  The next two digits, both 0, are selected and filled.  Since the x’21’ selected a leading 0, the
significance indicator is turned on - significance starts with the next digit.  This means that all other digits will appear in a character

http://csc.columbusstate.edu/woolbright/ED.HTM[9/21/2011 4:22:34 PM]


edit
Contents
representation, even if they are leading 0’s.  All other editing symbols will be printed as well.  The fifth digit, 0, is selected and
represented as x’F0’.  The x’4B’ is preserved.  The next two digits, 0 and 7, are selected and represented as x’F0’ and x’F7’. 
Finally, since the APK contains a negative number, the x’60’ is preserved.   The final result would print as “      0.07-”.
 
 

          Some Unrelated ED’s:


   
      APK       DC    PL2’123’   X’123C’
   AOUT      DS    CL4    
   AEDWD     DC    X’40202020’
                   ...             Result:
             MVC   AOUT,AEDWD
             ED    AOUT,APK       AOUT = X’40F1F2F3’ - ’ 123’
 
   BPK       DC    PL2’0’   X’000C’
   BOUT      DS    CL4    
   BEDWD     DC    X’40202020’
                   ...             Result:
             MVC   BOUT,BEDWD
             ED    BOUT,BPK       BOUT = X’40404040’ - ’    ’
 
   CPK       DC    PL2’0’   X’000C’
   COUT      DS    CL4    
   CEDWD     DC    X’40202120’
                   ...             Result:
             MVC   COUT,CEDWD
             ED    COUT,CPK       COUT = X’404040F0’ - ’   0’
 
 
 
 
 
 
   DPK       DC    PL2’0’   X’000C’
   DOUT      DS    CL4    
   DEDWD     DC    X’5C202120’   ASTERISK IS USED AS A FILL CHARACTER
 
 
                   ...             Result:
             MVC   DOUT,DEDWD
             ED    DOUT,DPK       DOUT = X’5C5C5CF0’ - ’***0’
 
 
   EPK       DC    PL2’-30’   X’030D’  NEGATIVE NUMBER
   EOUT      DS    CL4    
   EEDWD     DC    X’40202120’
                   ...             Result:
             MVC   EOUT,EEDWD
             ED    EOUT,EPK       EOUT = X’4040F3F0’ - ’  30’
 
 
   FPK       DC    PL2’-30’   X’030D’   NEGATIVE NUMBER
   FOUT      DS    CL5    OUTPUT FIELD IS LARGER TO ACCOMODATE EDIT WORD    
   FEDWD     DC    X’4020212060’
                   ...             Result:
             MVC   FOUT,FEDWD
             ED    FOUT,FPK       FOUT = X’4040F3F060’ - ’  30-’

 
1.  There are two errors that beginners make when using ED :
 
     1)  The number of x’20’s and x’21’s does not match the number of decimal digits in the field
           being edited.  This is a critical error.  If the packed field has length “n”, the number of
           x’20’s and x’21’s is 2n - 1.  For example, if you are editing a packed field of length 6, the
           edit word must contain exactly 11 x’20’s and x’21’s.  A bad edit word will produce
           unpredictable output.
 
     2)  The output field size does not match the edit word size.  For example, suppose you coded

http://csc.columbusstate.edu/woolbright/ED.HTM[9/21/2011 4:22:34 PM]


edit
Contents
          the following,
                  AEDWD     DC   X’402020202120’
                  AOUT      DS   CL5
          When the edit word is moved to AOUT, the last byte of the edit word is not moved since
          the edit word is 6 bytes and the target field is 5 bytes.  The effect is that we are using an
         incorrect edit word, even though the definition of the edit word was correct.
 
2)   When editing, start with the packed field and design an edit word that matches it.  Then define the output field to match the edit
word.  For example, if we start with a packed field of length 3 (5 decimal digits), we could design x’402021204B2020’ as an
appropriate edit word (5 x’20’s and x’21’s).  Since the edit word is 7 bytes long, we would design a 7 byte output field to hold the
edit word.
                   XPK       DS     PL3
                   XEDWD     DC     X’402021204B2020’
                   XOUT      DS     CL7
                             ...
                             MVC    XOUT,XEDWD
                             ED     XOUT,XPK

http://csc.columbusstate.edu/woolbright/ED.HTM[9/21/2011 4:22:34 PM]


edit and mark
Contents

 
   Packed decimal fields can be converted to a character format using the EDMK instruction.  Additionally, editing symbols and
features like commas, decimal points, and leading zero suppression can be included in the character version of the packed decimal
field that is being edited.  EDMK is equivalent to the ED instruction but offers additional functionality which will be covered later in
this discussion.
 
  The first step in editing a packed decimal field is to create an “edit word” which is a pattern of what the character output of the
edit process should look like.  Typically, the edit word is moved to a field in the output buffer which is being built, prior to printing. 
Then the packed decimal field is “edited” into the output field, destroying the copy of the edit word.
 
  First, we consider how to construct an appropriate edit word for a given packed decimal field.  This can be accomplished by
defining a string of hexadecimal bytes that represents the edit word.  Each byte in the edit word corresponds to a byte in the edited
character representation.  In creating the edit word there are a collection of standard symbols which are used to describe each
byte:
          X’40’        This symbol, which represents a space, is usually coded as the first byte of the
                          edit word where it acts as a “fill character”.  The fill character is used to replace
                          leading zeroes which are not “significant”.
 
          X’20’        Called a “digit selector”, this byte represents a position in which a
                          significant digit from the packed field should be placed.
  
          X’21’        This hexadecimal byte represents a digit selector and a significance starter. 
                          Significance starts when the first non-zero digit is selected.  Alternatively, we
                          can force significance to start by coding a single x’21’ in the edit word.  In this
                          case, significance starts in the byte following the x’21’.  Significance is
                          important because every significant digit is printed, even if it is a leading zero.
 
          X’6B’        This is the EBCDIC code for a comma. 
 
          X’4B’        This is the EBCDIC code for a decimal point.
 
          X’60’        This is the EBCDIC code for a minus sign.  This symbol is sometimes coded on
                          the end of an edit word when editing signed fields.  The  x’60’ byte will be
                          replaced with the fill character if the number being edited is positive.  If the
                          number is in fact negative, the x’60’ will not be “filled”, and the negative sign will
                          appear in the edited output.
 
          X’C4C2’   The EBCDIC version of “DB” (Debit).  This functions like the x’60’.  Coding
                          these symbols at the end of an edit word causes “DB” to appear in the output
                          if the field being edited is negative, otherewise the “DB” is “filled”.
 
          X’C3D9’   The EBCDIC version of “CR” (Credit).  This functions like the Debit symbol
                          above.  When the number being edited is negative, the “CR” symbol will
                          appear in the edited output, otherwise it will be “filled”.
          X’5C’        The EBCDIC symbol for an asterisk.  This character is sometimes used as
                          a fill character when editing dollar amounts on checks.
             
   We now consider a sample edit word and the output it would create for several packed fields.

http://csc.columbusstate.edu/woolbright/EDMK.HTM[9/21/2011 4:22:35 PM]


edit and mark
Contents
 
                    EDWD     DC    X’4020206B2021204B202060’
                    AOUT     DC    CL11
                    APK      DC    PL4’45387’  
 
Assume we execute the instructions below,
 
                    MVC      AOUT,EDWD
                    EDMK     AOUT,APK
 
First, the edit word is moved to a field in the output buffer.  Then the packed field is “edited” into the output field.   The results are
illustrated in the diagram below.
 

        
 
The diagram indicates the results of the edit process:  The fill character (x’40’) is unaffected, and is left in its position.  The first
decimal digit, 0, is “selected” by the first x’20’, and since leading 0’s are not significant, the x’20’ is replaced by the fill character. 
The second digit, 0, is also selected, and it too, is filled with a x’40’.  Since significance has not started, the x’6B’ is filled with
x’40’.  The first non-zero digit, 4, is selected and this signals that significance has started.  (Any non-zero digit which is selected
turns on the significance indicator.)  Each digit after the 4 will appear in the edited result.  The “4” is replaced with its character
equivalent - x’F4’.  At this point, the address of AOUT+4 (the position occupied by the first significant digit x’F4’, is copied into
register 1.  (The ED instruction would not initialize register 1.)  Afterward, the “5” is selected and its x’20’ is replaced with x’F5’. 
The “3” is selected and is represented as x’F3’.  The x’4B’, a decimal point, remains unaffected.  The “8” is selected and is
represented as x’F8’.  The “7” is selected and is represented as x’F7’.  Since the number being edited is positive, the x’60’ is filled
with x’40’.   The final result would print as “    453.87 “. 
 
 
   Consider a second edit which uses the same edit word as in the previous example, but with a different value for APK.
 
                    EDWD     DC    X’4020206B2021204B202060’
                    AOUT     DC    CL11
                    APK      DC    PL4’-7’  
 
Again we execute the same sequence of instructions.
 
                    MVC      AOUT,EDWD
                    EDMK     AOUT,APK
 

http://csc.columbusstate.edu/woolbright/EDMK.HTM[9/21/2011 4:22:35 PM]


edit and mark
Contents
 
As in every edit, the x’40’ fill character is unaffected by the edit process.  The first and second digits, both 0, are selected, and
since they are leading 0’s and significance has not started, they are filled with x’40’.  The x’6B’ is also filled with x’40’ since
significance has not started.  The next two digits, both 0, are selected and filled.  Since the x’21’ selected a leading 0, the
significance indicator is turned on - significance starts with the next digit.  This means that all other digits will appear in a character
representation, even if they are leading 0’s.  All other editing symbols will be printed as well.  Unlike the previous example, register
1 is not initialized because a significant digit was never encountered while the significance indicator was off. The fifth digit, 0, is
selected and represented as x’F0’.  The x’4B’ is preserved.  The next two digits, 0 and 7, are selected and represented as x’F0’
and x’F7’.  Finally, since the APK contains a negative number, the x’60’ is preserved.   The final result would print as “      0.07-”.
 
   It is important to understand that ED and EDMK are equivalent instructions except that under certain conditions, EDMK will
change the contents of register 1.  To be precise, EDMK sets register 1 to the address of the first non-zero digit in the target field if
the corresponding significant digit in the source field was encountered while the significance indicator was off.  Otherwise, register
1 is unaffected.  This gives rise to the common practice of initializing register 1 with the address of the byte following the
significance starter (x’21’) in the target field prior to issuing the EDMK instruction.  By doing this, the programmer can be assured
that register 1 is pointing at the first significant digit in the target, regardless of the manner in which significance was started. 
Consider the example below.
 
                       MVC  XOUT,EDWD   SET UP EDIT WORD
                       LA   R1,XOUT+4   POINT AT SIG.STARTER+1
                       EDMK XOUT,XPK    EDIT THE DATA   
                       ...
               XOUT    DS   CL7
               EDWD    DC   X’402020214B2020’ 
               XPK     DS   PL3
 
Suppose XPK contains x’00000C’.  After editing, XOUT contains “    .00”,  and register 1 contains the address of the decimal
point.  In this case the significance was turned on by the significance starter.
 
   On the other hand, suppose XPK contains x’05643C’.  After editing, XOUT contains “  56.43”, and register 1 contains the
address of the “5” XOUT.  In this case significance was started because a non-zero digit was selected while significance was off. 
In both of the previous cases, register 1 contains the address of the first significant digit.  The address in register 1 could be used
to insert an edititing character in front of the first significant digit:
 
                       MVI   0(R1),C’$’    FLOAT A DOLLAR SIGN
     

          Some Unrelated EDMK’s:


   
      APK       DC    PL2’123’   X‘123C’
   AOUT      DS    CL4    
   AEDWD     DC    X’40202120’
                   ...             Result:
             MVC   AOUT,AEDWD
             LA    R1,AOUT+3 
             ED    AOUT,APK       AOUT = X’40F1F2F3’ - ‘ 123’
                                  REGISTER 1 CONTAINS ADDRESS OF AOUT+1
   BPK       DC    PL2’0’   X‘000C’
   BOUT      DS    CL4    
   BEDWD     DC    X’40202120’
                   ...             Result:
             MVC   BOUT,BEDWD
             LA    R1,BOUT+3
             ED    BOUT,BPK       BOUT = X’404040F0’ - ‘    ’
                                  REGISTER 1 CONTAINS ADDRESS OF BOUT+3
   CPK       DC    PL2’0’   X‘000C’
   COUT      DS    CL4    
   CEDWD     DC    X’40212020’
                   ...             Result:
             MVC   COUT,CEDWD
             LA    R1,COUT+2
             ED    COUT,CPK       COUT = X’404040F0’ - ‘  00’
                                  REGISTER 1 CONTAINS ADDRESS OF COUT+3
 
   DPK       DC    PL2’0’   X‘000C’
   DOUT      DS    CL4    
   DEDWD     DC    X’5C202120’   ASTERISK IS USED AS A FILL CHARACTER
 

http://csc.columbusstate.edu/woolbright/EDMK.HTM[9/21/2011 4:22:35 PM]


edit and mark
Contents
 
                   ...             Result:
             MVC   DOUT,DEDWD
             LA    R1,DOUT+3
             ED    DOUT,DPK       DOUT = X’5C5C5CF0’ - ‘***0’
                                  REGISTER 1 CONTAINS ADDRESS OF DOUT+3
 
   EPK       DC    PL2’-300’   X’300D’  NEGATIVE NUMBER
   EOUT      DS    CL5    
   EEDWD     DC    X’4020212060’
                   ...             Result:
             MVC   EOUT,EEDWD
             LA    R1,EOUT+3
             ED    EOUT,EPK       EOUT = X’4040F3F0’ - ‘ 300-’
                                  REGISTER 1 CONTAINS ADDRESS OF EOUT+1
 
 

 
1.  There are two errors that beginners make when using EDMK :
 
     1)  The number of x’20’s and x’21’s does not match the number of decimal digits in the field
           being edited.  This is a critical error.  If the packed field has length “n”, the number of
           x’20’s and x’21’s is 2n - 1.  For example, if you are editing a packed field of length 6, the
           edit word must contain exactly 11 x’20’s and x’21’s.  A bad edit word will produce
           unpredictable output.
 
     2)  The output field size does not match the edit word size.  For example, suppose you coded
          the following,
                  AEDWD     DC   X’402020202120’
                  AOUT      DS   CL5
          When the edit word is moved to AOUT, the last byte of the edit word is not moved since
          the edit word is 6 bytes and the target field is 5 bytes.  The effect is that we are using an
         incorrect edit word, even though the definition of the edit word was correct.
 
2)   When editing, start with the packed field and design an edit word that matches it.  Then define the output field to match the edit
word.  For example, if we start with a packed field of length 3 (5 decimal digits), we could design x’402021204B2020’ as an
appropriate edit word (5 x’20’s and x’21’s).  Since the edit word is 7 bytes long, we would design a 7 byte output field to hold the
edit word.
                   XPK       DS     PL3
                   XEDWD     DC     X’402021204B2020’
                   XOUT      DS     CL7
                             ...
                             MVC    XOUT,XEDWD
                             LA     R1,XOUT+3
                             EDMK   XOUT,XPK
 
3)  Be sure to initialize R1 before issuing the EDMK instruction.  R1 should contain the address of the byte following the
significance starter (x’21’).

http://csc.columbusstate.edu/woolbright/EDMK.HTM[9/21/2011 4:22:35 PM]


ex
Contents

 
 
   The Execute instruction causes the computer to execute a “target” instruction which is referenced in Operand 2 and which is
typically placed out of the normal sequence of instructions, usually among a collection of DC’s or DS’s. After the target instruction
is executed, control returns to the instruction following the EX instruction unless the target instruction was a branch.  If  the target
instruction is a conditional branch, then control would resume at the address specified in the branch if the condition being tested is
true.  If the target instruction is an unconditional branch, then execution would resume at the address specified in the branch
instruction.  Typically, the target instruction is an MVC.
 
   If Operand 1 is not register zero, then the target instruction is temporarily modified before it is executed:  The rightmost byte of
the register specified by Operand 1 (bits 24 - 31) is “OR-ed” into the second byte of the target instruction.  Usually the second byte
contains x’00’ which means that the rightmost byte of Operand 1 is copied into the second byte of the target instruction just before
the target instruction is executed.  In the case where the target is an MVC instruction, the second byte is the length byte (the
number of bytes to be moved).  This means the length can be dynamically changed before executing the MVC instruction.  This is
an important reason to use EX.
 
   If Operand 1 is register zero, then the target instruction is executed without modification.  Here is an example.  We execute the
following instruction
      
        EX    R5,TARGET

 
 
   In the previous example the target instruction moves a field called “Y” to a field called “X”.  Notice that the length in operand 1 is
explicitly zero.  By coding this we guarantee that the second byte that is assembled for the MVC instruction contains x’00’.  Before
executing the target instruction, the length contained in the rightmost byte of register 5 (x’03’) is “Or-ed” into the second byte of the
MVC instruction.  Since this byte is all binary 0’s, the “Or” works like a copy.  At run-time, the length byte contains x’03’ which
causes 4 bytes to be moved into X. Remember that for MVC’s, the number of bytes in the object code is always 1 less than the
number of bytes that the machine moves.
 

http://csc.columbusstate.edu/woolbright/EX.HTM[9/21/2011 4:22:36 PM]


ex
Contents

        Some Unrelated EXs


 
              R4 =  X’00000005’  
              R5 =  X’FFFFFF04’
              R6 =  X’00000034’
 
              Instruction                                              Object Code
 
   TARGET1    MVC   FIELDA(0),FIELDB         D2 00 C0 10 C0 20
   TARGET2    AP    FIELDC(0),FIELDD(0)      FA 00 C0 22 C0 34
   TARGET3    LR    R0,R0                    18 00
 
              EX    R4,TARGET1  MOVES 6 BYTES FROM FIELDB TO FIELDA
              EX    R5,TARGET1  MOVES 5 BYTES (ONLY RIGHTMOST BYTE OF R5
                                DETERMINES THE LENGTH)
              EX    R6,TARGET1  MOVE 53 BYTES (LENGTH IS IN HEX)
              EX    R6,TARGET2  THE SECOND BYTE OF AN AP CONTAINS TWO
                                LENGTHS.  FIELDD (5 BYTES) IS ADDED TO
                                FIELDC (4 BYTES).
              EX    R6,TARGET3  THE SECOND BYTE OF AN LR SPECIFIES 2
                                REGISTERS.  REGISTER 4 IS LOADED INTO
                                REGISTER 3.
 

1.  The standard use for an execute instruction is to support variable length moves.  The previous examples illustrate that
instructions other than MVC can be executed but this should be carefully considered.  For instance, in executing an LR instruction,
the registers can be selected dynamically.  This is probably not a wise choice and may result in a program that is very difficult to
debug.
 
2.  When coding the target instruction, be sure and specify an explicit length of zero so the second byte of the machine code is
x’00’.
 
3.  Place the target instruction in a place where it will never be executed except as the target of an EX instruction.  Most
programmers put the target instructions among their DS’s and DC’s.
 
4.  While the target instruction can be any instruction except another EX instruction, you should limit the target instructions to
MVC’s.

http://csc.columbusstate.edu/woolbright/EX.HTM[9/21/2011 4:22:36 PM]


ic
Contents

 
 
   IC is used to copy a single byte from storage into the rightmost byte of a register.  The register is specified in operand 1, and the
one-byte storage location is denoted by operand 2.  Only the right-most byte of the register is changed.  All other bytes in the
register remain unchanged. Only the first byte of the field specified in storage is copied to the register.
 
 

 
 
 
   A common use of the  IC instruction is to move a one-byte binary length into the right-most byte of a register.  The register will
subsequently be used by an EX (Execute) instruction in order to move a variable number of bytes.  Here is an example of this
technique.
 
            TARGET    MVC   FIELDA(0),FIELDB
            LENGTH    DC    AL1(8)   A ONE-BYTE LENGTH = 8
                        ...
                      IC    R8,LENGTH  (INITIALLY 8,LENGTH MIGHT CHANGE)
                      EX    R8,TARGET   EXECUTE THE TARGET INSTRUCTION

    
    For the following examples, assume that R8 contains x’11223344’.
 
          FIELDA   DS    X’AABBCCDD’

http://csc.columbusstate.edu/woolbright/IC.HTM[9/21/2011 4:22:37 PM]


ic
Contents
          FIELDB   DS    C’ABCD’
          FIELDC   DC    AL1(8)
          FIELDD   DC    AL1(20)
                                             Result:
                   IC   R8,FIELDA   R8 = x’112233AA’
                   IC   R8,FIELDB   R8 = x’112233C1’
                   IC   R8,FIELDC   R8 = x’11223308’
                   IC   R8,FIELDD   R8 = x’11223314’
 

 
1.  It is a standard practice to use IC in conjunction with EX for moving variable length fields.  Remember that the inserted length of
“X” is treated as length “X + 1” when the MVC is executed.  In other words the assembled length in a MVC instruction is 1 less
than the actual length.

http://csc.columbusstate.edu/woolbright/IC.HTM[9/21/2011 4:22:37 PM]


icm
Contents

 
   ICM is used to copy consecutive bytes from memory into selected bytes of a register.  Up to 4 bytes can be copied into the
register which is specified by operand 1.  The bytes that are copied, come from consecutive bytes in memory specified by operand
3.  Additionally, the programmer supplies a mask (pattern), usually in binary, that indicates which bytes in the register should be
changed.  For example, a binary pattern of B’1010’ indicates that bytes 1 and 3 (numbering from left to right) are targets of the
copying operation.  A binary mask of B’0011’ indicates that two consecutive bytes from memory should be copied into the bytes 3
and 4 of the register.  Consider the following example.
 
 

 
 
    Often, ICM is used instead of  “LH” or “L“ to load halfwords and fullwords when these fields are not properly aligned.  The use of
a load instruction for a 4-byte field that is not aligned on a fullword produces a warning from the assembler.  Similar remarks apply
to the load halfword instruction.
 
 

    
    For the following examples, assume that R8 contains x’AABBCCDD’.
 
          FIELDA   DS    X’11223344’
          FIELDB   DS    C’ABCD’
          FIELDC   DC    HL2’20’   MAY NOT BE PROPERLY ALIGNED

http://csc.columbusstate.edu/woolbright/ICM.HTM[9/21/2011 4:22:38 PM]


icm
Contents
                                             Result:
                   ICM   R8,B’1100’,FIELDA   R8 = x’1122CCDD’
                   ICM   R8,B’0011’,FIELDA   R8 = x’AABB1122’
                   ICM   R8,B’1111’,FIELDA   R8 = x’11223344’
                   ICM   R8,B’1001’,FIELDA   R8 = x’11BBCC22’
                   ICM   R8,B’0101’,FIELDB   R8 = x’AAC1CCC2’
                   ICM   R8,B’0011’,FIELDC   R8 = x’AABB0014’
                                             Binary 20 = x’0014’
                   ICM   R8,3,FIELDC         R8 = x’AABB0014’
                         Note - a decimal 3 = B’0011’ and so the last
                             two instructions are equivalent. It would
                             be better, however, to use a binary mask.

 
1.  Use ICM instead of load or load halfword when the field you are loading may not be properly aligned. 
 
2.  Remember that the mask applies to the bytes in the register and not the bytes in memory.  Bytes in memory are consecutively
loaded.
 
3.  It is good documentation to always use a binary self-defining term when creating the mask.  

http://csc.columbusstate.edu/woolbright/ICM.HTM[9/21/2011 4:22:38 PM]


LOAD
Contents

 
 
   L is used to copy the fullword stored in the memory location designated by operand 2 into the register specified by operand 1. 
Consider the following example,    
 
                            L    R9,AFIELD       
 

   The contents of the fullword “AFIELD” are copied to register 9, destroying the previous values in R9.  The fullword is unchanged
by this operation.
 
   Since L is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 

          Some Unrelated Loads


 
              R4 =  X’12121212’
              R5 =  X’00000008’
              R6 =  X’00000004’    
  
    AFIELD   DC  F’4’       AFIELD = X’00000004’
    BFIELD   DC  F’-1’      BFIELD = X’FFFFFFFF’
    CFIELD   DC  F’0’       CFIELD = X’00000000’
   
             L   R4,AFIELD     R4 = X’00000004’
             L   R4,AFIELD(R6) R4 = X’FFFFFFFF’
             L   R4,AFIELD(R5) R4 = X’00000000’
             L   R6,AFIELD(R6) R6 = X’FFFFFFFF’
 
             CONSIDER THE NEXT TWO CONSECUTIVELY EXECUTED LOADS
             L   R5,AFIELD     R5 = X’00000004’
             L   R6,AFIELD(R5) R6 = X’FFFFFFFF’

http://csc.columbusstate.edu/woolbright/L.HTM[9/21/2011 4:22:39 PM]


load address
Contents

 
 
   LA is used to initialize the register specified by operand 1 with the address designated by operand 2.  Operand 2 may be
expressed using explicit notation ( see Explicit Addressing) or symbolic notation, or a combination of both.  Remember that each
byte in memory is numbered and that the number assigned to a byte is its address.  The address of a field is the address of the
first byte of the field.  Consider the following example,    
 
                            LA    R9,AFIELD       
 

 
   The address of the fullword “AFIELD” , x’00001000’, is copied to register 9, destroying the previous value in R9.  The fullword is
unchanged by this operation.
 
   Since LA is an RX instruction, an index register may be coded as part of operand 2 as in the example below.  We assume that
register 6 is used as an index register and initially contains x’0000002F’.  When the assembler processes the expression
AFIELD(R6), it uses the symbol AFIELD to determine a base register and a displacement, leaving R6 as the index register.  The
address which is loaded into register 9 is the “effective address” computed by adding the base register contents, plus the index
register contents, plus the displacement:
 
       Effective address = C(Base register) + C(Index register) + displacement
 
We assume that the contents of the base register plus the displacement is x’00001000’.  Then the effective address is x’00001000’
+ x’0000002F’ = x’0000102F’ .
 
 
 
 
 
 
 
 
 
 
 
                            LA    R9,AFIELD(R6)
 

http://csc.columbusstate.edu/woolbright/LA.HTM[9/21/2011 4:22:40 PM]


load address
Contents

       
 
   The example above uses a mixture of symbolic and explicit addressing.  The instruction could also be coded using only explicit
addresses:
 
                            LA   R9,30(R7,R8)
 
In the example above assume that R7 contains x’00001000’ and that R8 contains x’00000020’.  R7 is treated as an index register,
R8 is the base register, and 30 is a displacement.  The effective address is C(R7) + C(R8) + 30 = x’00001000” + x’00000020’ +
x’0000001E’ = x’0000103E’.  (Remember that a decimal 30 is 1E in hexadecimal.)  After the instruction has executed, R9 contains
x’0000103E’.
 

          Some Unrelated Load Addresses


 
              R4 =  X’12121212’
              R5 =  X’00000008’
              R6 =  X’00000004’  
    Assume that AFIELD has address x’00003000’. 
  
    AFIELD   DC  F’4’       AFIELD = X’00000004’
 
             LA  R4,AFIELD     R4 = X’00003000’
             LA  R4,AFIELD(R6) R4 = X’00003004’
             LA  R4,AFIELD(R5) R4 = X’00003008’
             LA  R4,20(R5,R6)  R4 = X’00000020’  4 + 8 + 20 = 32 = X’20’
 
             Using R0 as an index indicates that no index register is
             desired:
 
             LA  R4,3(R0,R6)   R4 = X’00000007’  4 + 3 = 7
        
 
 
 
 
             Consider the next two consecutively executed instructions.
 
             LA  R4,AFIELD            R4 = X’00003000’
             LA  R4,L’AFIELD(R0,R4)   R4 = x’00003004’
 
             In the example above, the length attribute (L’) is used as
             a displacement
 

1.  An old assembler joke:


 
         Novice:  What’s the difference between a Load instruction and a Load Address
                       instruction?”
 

http://csc.columbusstate.edu/woolbright/LA.HTM[9/21/2011 4:22:40 PM]


load address
Contents
         Old Hand:  About a week -  of debugging.
 
   Seriously, you should pay attention when coding L or LA.  Both instructions compute the address of operand 2.  In the case of
L,  the machine retrieves the contents of the fullword in memory at the specified address and places the four bytes in a register.  In
the case of LA, the address is simply stored in a register.           
 
2.  The LA instruction is often used to change the location referenced by a DSECT:
 
                  TEST     DSECT
                  TESTREC  DS  0CL80
                  X        DS   ...
 
                           USING  TEST,R5
 
                           LA    R5,TABLE     POINT AT TABLE AREA
                           ...  
                           LA    R5,L’TESTREC(R0,R5)  MOVE THE DSECT
 
   (See DSECTs.)

http://csc.columbusstate.edu/woolbright/LA.HTM[9/21/2011 4:22:40 PM]


load complement register
Contents

                                                             
 
   The Load Complement instruction copies the two’s complement value (See Binary Arithmetic)  of  the contents of the register
specified by Operand 2, into the register specified by Operand 1.  The contents of Operand 2 are unchanged by this operation. 
Remember that if you add an integer and its two’s complement, the result is zero.  (The two’s complement of 5 is -5.  The two’s
complement of -33 is 33.)  LCR sets the condition code based on the final contents of the Operand 1 register.
 
                                    Condition Code         Meaning             Test With
 
                                       0   (Zero)                 Operand 1 = 0         BE, BZ
                                       1   (Negative)          Operand 1 < 0         BL, BM
                                       2   (Positive)            Operand 1 > 0         BH, BP
                                       3   (Overflow)           Overflow                 BO
 
An overflow condition can occur only when Operand 2 contains the maximum negative value that will fit in a register (-
2,147,483,648).  An overflow occurs because the complement will not fit in a single register.
 
Consider the instruction below.  Assume R10 contains x’00000078’ = 120.
 
                            LCR   R5,R10
 
The contents of register 10 are complemented and copied to register 5, destroying the previous value in register 5. At completion,
register 5 contains a binary number equivalent to -120 in decimal. Register 10, which contains a binary number equal to 120 in
decimal, is unaffected by the operation.  Since the contents of R5 is negative after completion of the operation, the condition code
is set to 1.  The diagram below illustrates this operation.
 

            
 
 
 
 
 
 
 
 
 
 

http://csc.columbusstate.edu/woolbright/LCR.HTM[9/21/2011 4:22:41 PM]


load complement register
Contents

        Some Unrelated LCR’s


 
              R4 =  X’FFFFFFFF’  -1
              R5 =  X’00000028’  +40
              R6 =  X’80000000’  MAXIMUM NEGATIVE VALUE
              R7 =  X’00000000’  ZERO
  
 LCR    R4,R5   R4 = X’FFFFFFD8’ R5 = X’00000028’ Cond. Code = Negative
 LCR    R5,R4   R5 = X’00000001’ R4 = X’FFFFFFFF’ Cond. Code = Positive
 LCR    R5,R6   R5 = X’FFFFFFFF’ R6 = X’80000000’ Cond. Code = Overflow
 LCR    R6,R5   R6 = X’FFFFFFD8’ R5 = X’00000028’ Cond. Code = Negative
 LCR    R6,R7   R6 = X’00000000’ R7 = X’00000000’ Cond. Code = Zero
 LCR    R4,R4   R4 = X’00000001’ Cond. Code = Positive
 

http://csc.columbusstate.edu/woolbright/LCR.HTM[9/21/2011 4:22:41 PM]


lm
Contents

 
   LM is used to copy a set of consecutive fullwords in main storage into a  “consecutive” collection of registers.  The collection of
registers is specified by coding the beginning and ending registers as the first two operands.  For instance,
 
                      LM  R5,R8,XWORDS
 
would be used to load registers 5, 6, 7, and 8.  If the second operand specifies a lower register than the first operand, then a
“wrap-around” occurs.  For instance,
 
                      LM  R14,R12,12(R13)
 
would be used to load registers 14, 15, 0, 1, ..., 12 - every register except 13.
 
   The registers are loaded starting with the fullword at the address specified in the third operand.  In the first example above,
register 5 would be loaded with the fullword at XWORDS, register 6 with the fullword at XWORDS+4, register 7  with the fullword
at XWORDS+8, and  register 8 with the fullword at XWORDS+12.  In the second example, register 14 is loaded with the fullword at
the explicit address indicated as a 12 byte displacement off register 13.  Register 15 is loaded with the fullword at a 16 byte
displacement off register 13.  Register 0 is loaded with the fullword at a 20 byte displacement off register 13.  The remaining
registers are loaded in a similar manner.
 
   Here is an illustrated example.
 
                     STM   R7,R9,REGWORDS

   In the example above, the consecutive range of registers ( 7, 8, and 9 ) are loaded with three consecutive fullwords in memory
starting with the fullword specified as REGWORDS.
 

           Some Unrelated LM’s


 
      XWORD    DC    F’200’,F’50’,F’30’,F’90’
               ...

http://csc.columbusstate.edu/woolbright/LM.HTM[9/21/2011 4:22:42 PM]


lm
Contents
               LM    R5,R6,XWORD     R5  = F’200’
                                     R6  = F’50’
               LM    R15,R1,XWORD    R15 = F’200’
                                     R0  = F’50’
                                     R1  = F’30’
               LM    R4,R7,XWORD     R4  = F’200’
                                     R5  = F’50’
                                     R6  = F’30’
                                     R7  = F’90’
               LM    R14,R12,12(R13) THIS LOADS ALL REGISTERS EXCEPT 13
                                     STARTING WITH THE FULLWORD THAT
                                     IS 12 BYTES OFF REGISTER 13. (SEE
                                     PROGRAM LINKAGE.)  

1)  This instruction is helpful for creating subroutines.  Branch to a subroutine and immediately save the registers with STM.  This
allows your subroutine to freely use the registers.  Before exiting your subroutine, restore the registers with LM.  Create a register
“save area” for each subroutine.
 
                 BAS    R6,SUBRTN    CALL THE SUBROUTINE
                 ...
        SUBRTN   EQU    *
                 STM    R14,R12,SUBSAVE    SAVE THE REGISTERS
                 ... (SUBROUTINE CODE)
                 LM     R14,R12,SUBSAVE    RESTORE THE REGISTERS
                 BR     R6           BRANCH BACK TO CALLER 
        SUBSAVE  DS     15F          FIFTEEN FULLWORDS FOR THE REGISTERS
 
2)  Read about the role that LM plays in implementing the Program Linkage conventions.  

http://csc.columbusstate.edu/woolbright/LM.HTM[9/21/2011 4:22:42 PM]


load negative register
Contents

                                                             
 
   The Load Negative instruction copies the two’s complement of the absolute value of  the contents of the register specified by
Operand 2, into the register specified by Operand 1.  The contents of Operand 2 are unchanged by this operation.  Recall that
absolute value of an integer x, denoted by  | x | , is defined as follows,
 
                            | x |  =  x   if  x ³ 0  and | x | = -x   if x < 0
 
For example, | 7 | = 7 since 7 ³ 0, and | -5 | = 5 since -5 < 0.
 
   LNR insures that the contents of Operand 1 will be negative or zero after the operation has completed.  Negative integers and
zero are unchanged by this instruction.  For positive integers, the two’s complement of the integer is placed in Operand 1.
 
   The condition code is set by this instruction based on the final contents of Operand 1.
 
                                    Condition Code         Meaning             Test With
 
                                       0   (Zero)                 Operand 1 = 0         BE, BZ
                                       1   (Negative)           Operand 1 <  0       BM, BL
                                     
An overflow condition can not occur.
 
Consider the instruction below.
 
                            LNR   R5,R10
 
The contents of register 10 are examined and determined to be positive.  As a result, the complement of the contents of register 10
are copied to register 5, destroying the previous value in register 5. Register 10, which contains a binary number equal to 120 in
decimal, is unaffected by the operation.  Since the contents of R5 are negative after completion of the operation, the condition code
is set to 1.  The diagram below illustrates this operation.
 

            
 
 
 

http://csc.columbusstate.edu/woolbright/LNR.HTM[9/21/2011 4:22:43 PM]


load negative register
Contents
        Some Unrelated LNR’s
 
              R4 =  X’FFFFFFFF’  -1
              R5 =  X’00000028’  +40
              R6 =  X’80000000’  MAXIMUM NEGATIVE VALUE
              R7 =  X’00000000’  ZERO
  
 LNR    R4,R5   R4 = X’FFFFFFD8’ R5 = X’00000028’ Cond. Code = Negative
 LNR    R5,R4   R5 = X’FFFFFFFF’ R4 = X’FFFFFFFF’ Cond. Code = Negative
 LNR    R5,R6   R5 = X’80000000’ R6 = X’80000000’ Cond. Code = Negative
 LNR    R6,R7   R6 = X’00000000’ R7 = X’00000000’ Cond. Code = Zero
 LNR    R4,R4   R4 = X’FFFFFFFF’ Cond. Code = Negative
 

http://csc.columbusstate.edu/woolbright/LNR.HTM[9/21/2011 4:22:43 PM]


Load halfword
Contents

 
 
   The LH instruction has two operands: the first operand is a general purpose register, and the second operand is a halfword in
memory.  The effect of the instruction is to place a 32-bit signed integer, algebraically equivalent to the 16-bit halfword, into
Operand 1. The 32-bit integer can be obtained by extending the sign-bit of the halfword so that it occupies 32 bits. (Extending the
sign bit of 2’s complement data does not change its arithmetic value.)  Consider the following example.    
 
                            LH    R9,AFIELD       
 

   The halfword “AFIELD”  contains a binary 1 in the sign-bit.  A sign-extended version of the halfword is copied into register 9,
destroying the previous values in the register.  The halfword is unchanged by this operation.
 
   Since LH is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 

          Some Unrelated Load Halfwords


 
              R4 =  X’00000000’
              R5 =  X’FFFFFFFF’
              R6 =  X’00000004’
           
    AFIELD   DC  H’4’       AFIELD = X’0004’
    BFIELD   DC  H’-1’      BFIELD = X’FFFF’
    CFIELD   DC  H’0’       CFIELD = X’0000’
   
             LH   R4,AFIELD     R4 = X’00000004’
             LH   R4,BFIELD     R4 = X’FFFFFFFF’
             LH   R4,CFIELD     R4 = X’00000000’
             LH   R4,DFIELD     R4 = X’FFFF
           
 
             CONSIDER THE NEXT TWO CONSECUTIVELY EXECUTED LOADS
             LH   R5,AFIELD     R5 = X’00000004’
             LH   R6,AFIELD(R5) R6 = X’FFFFFFFF’

http://csc.columbusstate.edu/woolbright/LOADHALF.HTM[9/21/2011 4:22:44 PM]


load positive register
Contents

                                                             
 
   The Load Positive instruction copies the absolute value of  the contents of the register specified by Operand 2, into the register
specified by Operand 1.  The contents of Operand 2 are unchanged by this operation.  Recall that absolute value of an integer x,
denoted by  | x | , is defined as follows,
 
                            | x |  =  x   if  x ³ 0  and | x | = -x   if x < 0
 
For example, | 7 | = 7 since 7 ³ 0, and | -5 | = 5 since -5 < 0.
 
   LPR insures that the contents of Operand 1 will be non-negative after the operation has completed if an overflow has not
occured.  Positive integers and zero are unchanged by this instruction.  For negative integers, the two’s complement of the integer
is placed in Operand 1.
 
   The condition code is set by this instruction based on the final contents of Operand 1.
 
                                    Condition Code         Meaning             Test With
 
                                       0   (Zero)                 Operand 1 = 0         BE, BZ
                                       2   (Positive)            Operand 1 > 0         BH, BP
                                       3   (Overflow)           Overflow                 BO
 
An overflow condition can occur only when Operand 2 contains the maximum negative value that will fit in a register (-
2,147,483,648).  An overflow occurs because the absolute value will not fit in a single register.
 
Consider the instruction below.
 
                            LPR   R5,R10
 
The contents of register 10 are examined and determined to be positive.  As a result, the contents of register 10 are copied to
register 5, destroying the previous value in register 5. Register 10, which contains a binary number equal to 120 in decimal, is
unaffected by the operation.  Since the contents of R5 is positive after completion of the operation, the condition code is set to 2. 
The diagram below illustrates this operation.
 

            
 
 
 

http://csc.columbusstate.edu/woolbright/LPR.HTM[9/21/2011 4:22:45 PM]


load positive register
Contents

        Some Unrelated LPR’s


 
              R4 =  X’FFFFFFFF’  -1
              R5 =  X’00000028’  +40
              R6 =  X’80000000’  MAXIMUM NEGATIVE VALUE
              R7 =  X’00000000’  ZERO
  
 LPR    R4,R5   R4 = X’00000028’ R5 = X’00000028’ Cond. Code = Positive
 LPR    R5,R4   R5 = X’00000001’ R4 = X’FFFFFFFF’ Cond. Code = Positive
 LPR    R5,R6   R5 = X’FFFFFFFF’ R6 = X’80000000’ Cond. Code = Overflow
 LPR    R6,R7   R6 = X’00000000’ R7 = X’00000000’ Cond. Code = Zero
 LPR    R4,R4   R4 = X’00000001’ Cond. Code = Positive
 

http://csc.columbusstate.edu/woolbright/LPR.HTM[9/21/2011 4:22:45 PM]


load register
Contents

                                                             
 
   The Load Register instruction copies the contents of the register specified by Operand 2, into the register specified by Operand
1.  The contents of Operand 2 are unchanged as well as the condition code. Consider the instruction below.
 
                            LR   R5,R10
 
The contents of register 10 are copied to register 5, destroying the previous value in register 5.  Register 10 is unaffected by the
operation.  The diagram below illustrates this operation.
 

            
 
 

        Some Unrelated LR’s


 
              R4 =  X’FFFFFFFF’
              R5 =  X’00000028’
              R6 =  X’00000004’
  
              LR    R4,R5    R4 = X’00000028’ R5 = X’00000028’
              LR    R5,R4    R5 = X’FFFFFFFF’ R4 = X’FFFFFFFF’
              LR    R5,R6    R5 = X’00000004’ R6 = X’00000004’
              LR    R6,R5    R6 = X’00000028’ R5 = X’00000028’

http://csc.columbusstate.edu/woolbright/LR.HTM[9/21/2011 4:22:46 PM]


load and test register
Contents

                                                             
 
   The Load and Test Register instruction copies the contents of the register specified by Operand 2, into the register specified by
Operand 1.  The contents of Operand 2 are unchanged by this operation.  In this respect LTR is equivalent to the LR instruction. 
The difference between these instructions is that LTR sets the condition code based on the final contents of the Operand 1
register.
 
                                    Condition Code         Meaning             Test With
 
                                       0   (Zero)                 Operand 1 = 0         BE, BZ
                                       1   (Negative)          Operand 1 < 0         BL, BM
                                       2   (Positive)            Operand 1 > 0         BH, BP
 
Consider the instruction below.
 
                            LTR   R5,R10
 
The contents of register 10 are copied to register 5, destroying the previous value in register 5.  Register 10 is unaffected by the
operation.  Since the contents of R5 is positive after completion of the operation, the condition code is set to 2.  The diagram below
illustrates this operation.
 

            
 
 
 
 
 
 
 
 
 
 

        Some Unrelated LTR’s


 
              R4 =  X’FFFFFFFF’
              R5 =  X’00000028’

http://csc.columbusstate.edu/woolbright/LTR.HTM[9/21/2011 4:22:47 PM]


load and test register
Contents
              R6 =  X’00000004’
              R7 =  X’00000000’
  
 LTR    R4,R5    R4 = X’00000028’ R5 = X’00000028’ Cond. Code = Positive
 LTR    R5,R4    R5 = X’FFFFFFFF’ R4 = X’FFFFFFFF’ Cond. Code = Negative
 LTR    R5,R6    R5 = X’00000004’ R6 = X’00000004’ Cond. Code = Positive
 LTR    R6,R5    R6 = X’00000028’ R5 = X’00000028’ Cond. Code = Positive
 LTR    R6,R7    R6 = X’00000000’ R7 = X’00000000’ Cond. Code = Zero
 LTR    R4,R4    R4 = X’FFFFFFFF’ Cond. Code = Negative
 

1)  LTR is commonly used to test the contents of a single register in order to determine if the binary number is the register is
positive, negative or zero.  For example, the following code illustrates how to test the contents of register 5.
 
                      LTR   R5,R5       SET THE CONDITION CODE
                      BM    NEGATIVE    IS R5 < 0 ?
                      BP    POSITIVE    IS R5 > 0?
             ZERO     EQU   *
                      ...
             NEGATIVE EQU   *     
                      ...
             POSITIVE EQU   *

http://csc.columbusstate.edu/woolbright/LTR.HTM[9/21/2011 4:22:47 PM]


MULTIPLY
Contents

 
 
   The Multiply instruction performs 2’s complement binary multiplication.  Operand 1 names an even register of an “even-odd”
consecutive register pair.  For instance, R2 would be used to name the R2 / R3 even-odd register pair, and R8 would be used to
name the R8 / R9 even-odd register pair.  Operand 2 is the name of a fullword in memory containing the multiplier.  Before the
multiplication, the even register can be left uninitialized, while the odd register contains the multiplicand.  After the multiplication,
the product occupies the even-odd register pair in 2’s complement format.

                   
 
   If the product is less than 2 31 - 1 = 2,147,483,647 then the answer can be found in the odd register.  We may then use CVD
and ED in order to print the product.  Otherwise, the even-odd pair must be treated as a large (64 bit) 2’s complement integer. 
Printing such an integer requires special treatment which we will consider later.  First, lets look at an example multiplication.  We
assume that AWORD is a fullword in memory containing the integer 10. 
 
                 L    R9,=F’47’   PUT MULTIPLICAND IN ODD REGISTER
                 M    R8,AWORD    MULTIPLY 47 TIMES 10  
 

        
 
    First the multiplicand, 47, is loaded into the odd register.  The even register is left uninitialized.  The multiplier, AWORD,
contains a 10 and is not affected by the multiplication.  After the multiplication, the register pair R8 / R9 contains a 64 bit 2’s
complement integer.  Since the product is sufficiently small, R9 by itself contains a valid representation of the product.
 
   When the product will not fit in the odd register, we must provide special handling in order to convert the product to a packed
representation.  If it takes two registers to hold the a result, we will call the answer a “double precision” result.  Unfortunately, there
is no instruction that will convert a 2’s complement double precision integer to a packed decimal format.  CVD can be used to
convert a single register to packed format, so we will investigate how this instruction can be used on both registers.  To simplify the
computations, we will assume that the registers contain 4 bits instead of 32.  Suppose a multiplication has produced a double
precision product of 83 in registers R4 and R5.  Then, since 83 = B’01010011’, and assuming 4 bit registers, R4 = B’0101’ and R5

http://csc.columbusstate.edu/woolbright/MULTIPLY.HTM[9/21/2011 4:22:48 PM]


MULTIPLY
Contents
= B’0011’.  If we use CVD to convert R4 we would get 5, when in fact, the bits in R4 represent 80 if we look at the 2’s complement
integer contained in R4 and R5.  We are off by a factor of 2 4 =16 since 5 x 16 = 80.  If we use CVD to convert R5 we would get 3,
which is what the bits in the double precision integer represent.  The true answer can be recovered by adding (5 x16) + 3.  This is
illustrated in the diagram below.

This procedure also works for some negative double precision integers.  Consider the double precision integer -108.  Using 4-bit
registers R4 and R5, we see that R4 contains B’1001’ and R5 contains B’0100’.  CVD converts R4 to  -7 when, in fact, the bits in
R4, B’1001’, represent -112 = -7 x 16.  R5 = B ‘0100’ is converted to 4.  Adding -112 + 4 we get the correct double precision
answer -108.  This is illustrated below.

 
   A problem with this method occurs when the odd register contains a 1 in the high-order bit.  Consider the double precision
integer 60 = B’00111100’.  Assume R4 contains B’0011’ and R5 contains B’1100’.  The conversion is illustrated  below.

R4 is converted to 3, multiplied by 16, and correctly converted to 48.  On the other hand, R5 is converted to -4 since the high
order bit was a 1.  R5 should have been converted to 12.  We are off by a factor or 16.  If we add 16, the conversion to 12 will be
correct.
 
   These examples lead us to a conversion algorithm for double precision results:
 
         1)  Test the odd register to see if it is negative.  If it is, we need to add 2 32 = 4,294,967,296 ( we are using 32-bit registers
instead of 4-bit registers ) to the final result.  An easy way to do this is by adding 1 to the even register - the rightmost bit in the
even register represents 2 32 .
 
         2)  Convert the even register to packed decimal and multiply the result by 2 32 .
 

http://csc.columbusstate.edu/woolbright/MULTIPLY.HTM[9/21/2011 4:22:48 PM]


MULTIPLY
Contents
         3)  Add in the result of converting the odd register to packed decimal.
 
   Here is an example in assembler language of the algorithm described above.  The example illustrates how a double precision
result in R4 and R5 could be converted to packed decimal in a doubleword.
 
               LTR    R5,R5          DOES R5 LOOK NEGATIVE?
               BNM    LOOKSPOS       DON’T ADD TO R4 IF POSITIVE
               A      R4,=F’1’       WE ARE OFF BY 2 TO THE 32 POWER
     LOOKSPOS  EQU    *
               CVD    R4,RESULTRT    CONVERT AND GET READY..
               MP     RESULT,TWOTO32 MULTIPLY BY 2 TO THE 32
               CVD    R5,DOUBWORD    CONVERT ODD REG TO DECIMAL
               AP     RESULT,DOUBWORD ADD THE TWO COMPONENTS
               ...
     RESULT    DS    0PL16   NEED A LARGE AREA TO HOLD DOUBLE PRECISION
     RESULTLF  DC     X’00000000’ NEEDS TO BE 0’S AFTER CONVERTING R4
     RESULTRT  DS     PL6    WORK AREA FOR R4
     TWOTO32   DC     P’4294967296’  2 TO THE 32ND POWER
     DOUBWORD  DS     D      CONVERSION AREA FOR CVD
              

          Some Unrelated Multiply Instructions


 
       L    R7,=F’100’   MULTIPLICAND GOES IN THE ODD REGISTER
       M    R6,=F’10     R6 = X’00000000’ = 0, R7 = X’000003E8’ = 1000
 
       L    R7,=F’3’     MULTIPLICAND GOES IN THE ODD REGISTER
       M    R6,=F’-2’    R6 = X’FFFFFFFF’, R7 = X’FFFFFFFA’ = -6
 
       L    R3,=F’8’     MULTIPLICAND GOES IN THE ODD REGISTER
       M    R2,=F’1’     R2 = X’00000000’, R3 = X’00000008’
 
       L    R3,=F’8’     MULTIPLICAND GOES IN THE ODD REGISTER
       M    R2,=F’0’     R2 = X’00000000’, R3 = X’00000000’
 
       L    R5,=X’FFFFFFFF’    ALL 1’S IN ODD REG
       M    R4,=F’2’     MULTIPLYING BY 2 SHIFTS ALL BITS 1 BIT LEFT
                         R4 = X’00000001’, R5 = X’FFFFFFFD’, THIS IS A
                         DOUBLE PRECISION RESULT

1)  Know your data!  In most cases, the product of a multiplication will fit in the odd register where it can easily be converted back
to packed decimal.  If you have any doubts about the size of a generated product, you must convert the double precision result
from both the even and odd registers as described above.

http://csc.columbusstate.edu/woolbright/MULTIPLY.HTM[9/21/2011 4:22:48 PM]


multpack
Contents

 
 
   MP is a SS 2 instruction which is used to multiply packed decimal fields.  Operand 1 is a field in storage which initially contains a
packed decimal number representing the multiplicand.  The product develops in this field, destroying the multiplicand.  The
contents of Operand 2, another packed decimal field in storage, represents the multiplier.  This field is unchanged by the
multiplication (unless it also participates as operand 1).  The condition code is not set by this instruction.
 
   There are three rules that must be followed concerning the lengths of the fields that participate in a multiply packed instruction.
 
   1)  The multiplier is limited to a maximum of 8 bytes.
 
   2)  The multiplicand field can be as large as 16 bytes.
 
   3)  If the length of operand 2 is “L2”, then the multiplicand must contain at least L2 bytes of leading zeroes before the instruction
is executed.
 
 For example,
 
               APK      DC    PL4’12345’     = X’0012345C’
               BPK      DC    PL2’100’       = X’100C’
                        ...
                        MP    APK,BPK
 
The MP above causes an “0C6” abend because APK contains 1 byte of leading zeroes and BPK is 2 bytes long.  In order to
multiply APK and BPK above, we must code a work area that is large enough to support a sufficient number of leading zeroes. 
Adding the lengths of both fields we see that a field of length 6 is large enough to prevent this problem.
 
               WORK     DS    PL6
                        ...
                        ZAP   WORK,APK
                        MP    WORK,BPK
 
 
 
 
 
 

          Some unrelated MP’s:


 
 A        DC      P’25645’     = X’25645C’
 B        DC      P’11’        = X’011C’    
 C        DC      P’-4’        = X’4D’
 D        DC      P’9876543’   = X’9876543C’    4 BYTE FIELD
 WORK     DS      PL6
          ...
                              Results:
          ZAP   WORK,A      WORK = X’00000025645C’ 3 BYTES LEADING 0’S
          MP    WORK,=P’20’ WORK = X’00000512900C’ 
 
          ZAP   WORK,B      WORK = X’00000000011C’ 4 BYTES LEADING 0’S 
          MP    WORK,B      WORK = X’00000000121C’ 

http://csc.columbusstate.edu/woolbright/MULTPACK.HTM[9/21/2011 4:22:49 PM]


multpack
Contents
 
          ZAP   WORK,A      WORK = X’00000025645C’ 3 BYTES LEADING 0’S
          MP    WORK,B      WORK = X’00000282095C’ 
 
          ZAP   WORK,A      WORK = X’00000025645C’ 3 BYTES LEADING 0’S
          MP    WORK,D      ABEND (0C6) - NOT ENOUGH LEADING 0’S
 
          MP    A,B         ABEND - NOT ENOUGH LEADING 0’S IN “A”
 

 
1. When creating a work field for a multiplication, the rule of thumb is to make the work area at least as large as the sum of the
fields that contain the multiplicand and the multiplier.  There is no harm in overestimating the size of the work area, but an area
that is too small will cause an abend.

http://csc.columbusstate.edu/woolbright/MULTPACK.HTM[9/21/2011 4:22:49 PM]


Multiply Halfword
Contents

 
 
   The Multiply Halfword instruction performs 2’s complement binary multiplication.  Operand 1 names a single register (even or
odd) which will contain the multiplicand.  Operand 2 is the name of a halfword in memory containing the multiplier.  After the
multiplication, the product is left in Operand 1, destroying the multiplicand.  It is possible to generate a product that will not fit in a
single register, but an overflow will not be indicated.  Leftmost bits in the product could be truncated to 32 bits in Operand 1.  The
programmer must be aware of the limits of the data being processed and protect against the possibilities of overflows.  Select a
fullword multiplication (M) if you are unsure of your data.
 
    Assume you want to multiply a fullword field called “COST” by a halfword field called “NOITEMS”.   The following code would
accomplish this task and leave the product in register 5.
 
                        L    R5,COST
                        MH   R5,NOITEMS
                  

        Some Unrelated Multiply Halfword Instructions


 
       L    R6,=F’100’   MULTIPLICAND GOES IN ANY REGISTER
       MH   R6,=F’10     R6 = X’000003E8’ = 1000
 
       L    R7,=F’3’     MULTIPLICAND GOES IN ANY REGISTER
       MH   R7,=F’-2’    R7 = X’FFFFFFFA’ = -6
 
       L    R3,=F’8’     MULTIPLICAND GOES IN ANY REGISTER
       MH   R3,=F’2’     R3 = X’00000010’ = 16    
 
       L    R3,=F’8’     MULTIPLICAND GOES IN ANY REGISTER
       MH   R3,=F’0’     R3 = X’00000000’ = 0
 
       L    R4,=X’7FFFFFFF’  LARGEST POSITIVE NUMBER IN A SINGLE REG.
       MH   R4,=F’2’     MULTIPLYING BY 2 CAUSES OVERFLOW
                         R4 = X’FFFFFFFE’ = -2   INCORRECT RESULT
 
 
 
 
 
 
 
 
 

1)  Know your data!  To use MH, one of the operands must be small enough to fit in a halfword.  This range is -32768 to +32,767. 
The product of the multiplication must fit in a single register where the range of integers is -2,147,483,648 to +2,147,483,647. In
many cases, the product of a multiplication will fit in a single register.   If you have any doubts about the size of a generated
product, use M instead of MH.

http://csc.columbusstate.edu/woolbright/MULTHALF.HTM[9/21/2011 4:22:50 PM]


MULTIPLY REGISTER
Contents

 
 
   The Multiply Register instruction performs 2’s complement binary multiplication.  Operand 1 names an even register of an “even-
odd” consecutive register pair.  For instance, R2 would be used to name the R2 / R3 even-odd register pair, and R8 would be
used to name the R8 / R9 even-odd register pair.  Operand 2 names a register containing the multiplier.  Before the multiplication,
the even register can be left uninitialized, while the odd register contains the multiplicand.  After the multiplication, the product
occupies the even-odd register pair in 2’s complement format.

                   
 
   If the product is less than 2 31 - 1 = 2,147,483,647 then the answer can be found in the odd register.  We may then use CVD
and ED in order to print the product.  Otherwise, the even-odd pair must be treated as a large (64 bit) 2’s complement integer. 
Printing such an integer requires special treatment we will examine later.  First, lets look at an example multiplication.
 
                                   L    R9,=F’47’   PUT MULTIPLICAND IN ODD REGISTER
                 L    R5,=F’10’   PUT MULIPLIER IN A REGISTER
                 MR   R8,R5       MULTIPLY EVEN/ODD PAIR(8/9)TIMES R5  
 

 
    First the multiplicand, 47, is loaded into the odd register.  The even register is left uninitialized and is shown above to contain
x’000AB356’ (this is arbitrary).  The integer 10 is loaded into R5 and acts as the multiplier.  After the multiplication, the register pair
R8 / R9 contains a 64 bit 2’s complement integer representing the product.  Since the product is sufficiently small, R9 by itself
contains a valid representation of the product.
 
   When the product will not fit in the odd register, we must provide special handling in order to convert the product to a packed
representation.  If it takes two registers to hold the a result, we will call the answer a “double precision” result.  Unfortunately, there
is no instruction that will convert a 2’s complement double precision integer to a packed decimal format.  CVD can be used to
convert a single register to packed format, so we will investigate how this instruction can be used on both registers.  For the
purposes of demonstration, and to simplify the computations, we will assume that the registers contain 4 bits instead of 32. 

http://csc.columbusstate.edu/woolbright/MULTREG.HTM[9/21/2011 4:22:51 PM]


MULTIPLY REGISTER
Contents
Suppose a multiplication has produced a double precision product of 83 in registers R4 and R5.  Since 83 = B’01010011’, and
assuming 4 bit registers, R4 = B’0101’ and R5 = B’0011’.  If we use CVD to convert R4 we would get 5, when in fact, the bits in R4
represent 80 if we look at the 2’s complement integer contained in R4 and R5.  We are off by a factor of 2 4 =16 since 5 x 16 =
80.  If we use CVD to convert R5 we would get 3, which is what the bits in the double precision integer represent.  The true
answer can be recovered by adding (5 x16) + 3.  This is illustrated in the diagram below.

This procedure also works for some negative double precision integers.  Consider the double precision integer -108.  Using 4-bit
registers R4 and R5, we see that R4 contains B’1001’ and R5 contains B’0100’.  CVD converts R4 to  -7 when, in fact, the bits in
R4, B’1001’, represent -112 = -7 x 16.  R5 = B ‘0100’ is converted to 4.  Adding -112 + 4 we get the correct double precision
answer -108.  This is illustrated below.

 
 
 
   A problem with this method occurs when the odd register contains a 1 in the high-order bit.  Consider the double precision
integer 60 = B’00111100’.  Assume R4 contains B’0011’ and R5 contains B’1100’.  The conversion is illustrated  below.

R4 is converted to 3, multiplied by 16, and correctly converted to 48.  On the other hand, R5 is converted to -4 since the high
order bit was a 1.  R5 should have been converted to 12.  We are off by a factor or 16.  If we add 16, the conversion to 12 will be
correct.
 
   These examples lead us to a conversion algorithm for double precision results:
 
         1)  Test the odd register to see if it is negative.  If it is, we need to add 2 32 = 4,294,967,296 ( we are using 32-bit registers
instead of 4-bit registers ) to the final result.  An easy way to do this is by adding 1 to the even register - the rightmost bit in the
even register represents 2 32 .

http://csc.columbusstate.edu/woolbright/MULTREG.HTM[9/21/2011 4:22:51 PM]


MULTIPLY REGISTER
Contents
 
         2)  Convert the even register to packed decimal and multiply the result by 2 32 .
 
         3)  Add in the result of converting the odd register to packed decimal.
 
   Here is an example in assembler language of the algorithm described above.  The example illustrates how a double precision
result in R4 and R5 could be converted to packed decimal in a doubleword.
 
               LTR    R5,R5          DOES R5 LOOK NEGATIVE?
               BNM    LOOKSPOS       DON’T ADD TO R4 IF POSITIVE
               A      R4,=F’1’       WE ARE OFF BY 2 TO THE 32 POWER
     LOOKSPOS  EQU    *
               CVD    R4,RESULTRT    CONVERT AND GET READY..
               MP     RESULT,TWOTO32 MULTIPLY BY 2 TO THE 32
               CVD    R5,DOUBWORD    CONVERT ODD REG TO DECIMAL
               AP     RESULT,DOUBWORD ADD THE TWO COMPONENTS
               ...
     RESULT    DS    0PL16   NEED A LARGE AREA TO HOLD DOUBLE PRECISION
     RESULTLF  DC     X’00000000’ NEEDS TO BE 0’S AFTER CONVERTING R4
     RESULTRT  DS     PL6    WORK AREA FOR R4
     TWOTO32   DC     P’4294967296’  2 TO THE 32ND POWER
     DOUBWORD  DS     D      CONVERSION AREA FOR CVD
              
 
 
 
 
 
 
 
 
 
 
 

          Some Unrelated Multiply Register Instructions


 
       L    R7,=F’100’   MULTIPLICAND GOES IN THE ODD REGISTER
       L    R9,=F’10’    MULTIPLIER GOES IN R9
       MR   R6,R9        R6 = X’00000000’ = 0, R7 = X’000003E8’ = 1000
 
       L    R7,=F’3’     MULTIPLICAND GOES IN THE ODD REGISTER
       L    R6,=F’-2’    MULTIPLIER CAN OCCUPY THE EVEN REGISTER!
       MR   R6,R6        OPERAND 1 INDICATES EVEN/ODD PAIR R6/R7
                         OPERAND 2 INDICATES THE MULTIPLIER - R6
                         R6 = X’FFFFFFFA’
 
       L    R3,=F’8’     MULTIPLICAND GOES IN THE ODD REGISTER
       L    R2,=F’1’     MULTIPLIER GOES IN R2
       MR   R2,R2        R2 = X’00000000’, R3 = X’00000008’
 
       L    R3,=F’8’     MULTIPLICAND GOES IN THE ODD REGISTER
       L    R8,=F’0’     MULTIPLIER GOES IN R8
       M    R2,R8        R2 = X’00000000’, R3 = X’00000000’
 
       L    R5,=X’FFFFFFFF’    ALL 1’S IN ODD REG = -1
       L    R9,=F’2’     MULTIPLIER GOES IN R9
       MR   R4,R9       
                         R4 = X’FFFFFFFF’, R5 = X’FFFFFFFE’, THIS IS A
                         DOUBLE PRECISION RESULT = -2

1)  Know your data!  In most cases, the product of a multiplication will fit in the odd register where it can easily be converted back
to packed decimal.  If you have any doubts about the size of a generated product, you must convert the double precision result
from both the even and odd registers as described above.
 
2)  Rather than leave the even register uninitialized, you can use it to hold the multiplier.  If you do this, the multiplier will be

http://csc.columbusstate.edu/woolbright/MULTREG.HTM[9/21/2011 4:22:51 PM]


MULTIPLY REGISTER
Contents
destroyed since the product occupies the even/oddd register pair.

http://csc.columbusstate.edu/woolbright/MULTREG.HTM[9/21/2011 4:22:51 PM]


mvc
Contents

 
   MVC is an instruction which is designed to copy a collection of consecutive bytes from one storage location to another.  As you
can see from the instruction format above, the instruction carries with it  the number of bytes to be copied, as well as the beginning
addresses of the source and target fields.  Notice that the instruction does not specify the ending addresses of either field - the
instruction is no respecter of fields.  MVC copies LL 1 + 1 consecutive bytes from the storage location designated by B2 D 2 D 2 D 2  to
the storage location designated by B1 D 1 D 1 D 1 .  The copying occurs one byte at a time from Operand 2 to Operand 1, and within
each operand, from lower to higher numbered addresses.
  
   The length (LL1 ) determines the number of bytes which will be copied.  The length is usually determined implicitly from the
length of operand 1 but the programmer can provide an explicit length.   Consider the two example MVC’s below,
 
     Object code                            Assembler code
 
                   FIELDA    DS        CL8
                   FIELDB    DS        CL5
                             ...     
  D207C008C010               MVC     FIELDA,FIELDB     Implicit length
  D202C008C010               MVC     FIELDA(3),FIELDB  Explicit length
 
In the first example, the length implicitly defaults to 8, the length of FIELDA.  In the second example, the length is explicitly 3.
Notice that the assembled length (LL1 ) is one less than the implicit or explicit length.  This can be seen in the object code above
where  the assembled lengths are x’07’ and x’02’.
 
   The copying operation is usually straightforward, but can be more complicated by overlapping the source and target fields.  Keep
in mind that the copy is made one byte at a time.  Consider the following examples,
 
     Object code                        Assembler code
 
                ONE       DC    C’1’
                FIELDA    DC    CL3’ABC’
                FIELDB    DC    CL3’DEF’
                FIELDC    DC    CL4’1234’
                          ...     
  D202C008C00B            MVC   FIELDA,FIELDB    After FIELDA = ’DEF’
  D201C00EC008            MVC   FIELDC,FIELDA    After FIELDC = ’ABCD’  
  D201C008C007            MVC   FIELDA,ONE       After FIELDA = ’1111’  
 
In the first MVC above, 3 consecutive bytes in FIELDB are simply copied to FIELDA.  In the second example, 4 consecutive bytes
are copied into FIELDC (implicit length = 4) from FIELDA.  Since FIELDA was only 3 bytes long the fourth byte was copied from
the first byte of the next field - FIELDB. The third MVC is complicated by the fact that the source and target fields overlap.  We will
examine the third move in some detail.
 

http://csc.columbusstate.edu/woolbright/MVC.HTM[9/21/2011 4:22:52 PM]


mvc
Contents

 
 
The example above depends heavily on the fact that the source and target fields overlap and that bytes are copied one at a time. 
In fact, it is common to use this technique to clear fields.  Assume you have a buffer you would like to clear to spaces.  By defining
a single blank directly in front of the field you want to clear and moving the blank field to the buffer, the blank can be propagated
throughout the buffer:
 
                      MVC   BUFFER,BLANK         BLANK IS PROPAGATED
                      ...
             BLANK    DC    C’’      BLANK MUST IMMEDIATELY PRECEDE…   
                                       
             BUFFER   DS    CL133    …THE BUFFER
 

          Some Unrelated MVC’s:


 
      A         DC    C’123’
   B         DC    C’ABCD’    
   C         DC    C’PQ’
                   ...             Result:
             MVC   A,B            A = ’ABC’    B = ’ABCD’
             MVC   A+1,B          A = ’1AB’    B = ’CBCD’
             MVC   A+1(2),B       A = ’1AB’    B = ’ABCD’
             MVC   B,=C’XY’       B = ’XY??’   Two bytes copied from
                                               the literal pool, two
                                               unknown bytes are copied
             MVC   B,B+1          B = ’BCDP’   Left shift
             MVC   B+1,B          B = ’AAAA’   First byte is propagated
             MVC   C,A            C = ’12’  A = ’123’  Truncation
             MVC   A(L’C),C       A = ’PQ3’   Explicit Length attribute                 
             MVC   A(1000),B    Assembly Error - max length is 256 bytes
             MVC   A,B(20)      Assembly Error - Op-1 determines length

 
1.  Pay attention to the lengths of the fields involved in any MVC statement.  If the target field is longer than the source field, bytes
following the source may be transferred.  If the target field is shorter than the source field, bytes from the source may may be
truncated.
 
2.  Be careful of using literals in an MVC, since stray bytes in the literal pool will be moved if the specified length is longer than

http://csc.columbusstate.edu/woolbright/MVC.HTM[9/21/2011 4:22:52 PM]


mvc
Contents
the literal.  Lengths can also be specified in a literal  (=CL133’ ‘).  The following typical error   MVC   BUFFER,=C’ ‘  can be fixed
as MVC   BUFFER,=CL80’ ‘.
 

http://csc.columbusstate.edu/woolbright/MVC.HTM[9/21/2011 4:22:52 PM]


Contents

   There is a 256 byte limitation when moving character data with MVC.  If a field is larger than 256 bytes, one solution to moving it
in memory is to divide it into multiple parts and code multiple MVC’s.  A more elegant solution involves the Move (Characters) Long
instruction (MVCL) which was designed for fields longer than 256 bytes.  In fact, up to 2 24 = 16,777,216 bytes can be moved with
one MVCL instruction.  This instruction is unusual because it requires the use of four registers.  Operand 1 and operand 2, denoted
by R1 and R2, each represent the even register of an even-odd consecutive register pair (2-3, 4-5, 6-7, …).  For example, if you
coded “MVCL R4,R8”  the registers involved would be R4, R5, R8, and R9.  The even registers contain the address of target and
source fields, while the odd registers contain the lengths of target and source fields.  Additionally, a pad character can be placed in
the high order byte of the odd register which contains the length of the source field. The pad character is used to fill up the target
field when the source field is shorter and all of its contents have been transmitted.  Here is a simple example in which we want to
move FIELDB to FIELDA:
 
                             LA    R4,FIELDA          POINT AT TARGET FIELD WITH EVEN REG
                             L     R5,LENGTHA         PUT LENGTH OF TARGET IN ODD REG
                             LA    R6,FIELDB          POINT AT SOURCE FIELD WITH EVEN REG
                             L     R7,LENGTHB         PUT LENGTH OF SOURCE IN ODD REG
                             ICM   R7,B’1000’,BLANK   INSERT A SINGLE BLANK PAD CHAR IN ODD REG
                             MVC   R4,R6
                             …
                    FIELDA   DC    CL2000’ ’
                    BDATA    DC    1000CL1’X’
                             ORG   BDATA
                    FIELDB   DS    CL1000
                    LENGTHA  DC    A(L’FIELDA)        CREATE AN ADDRESS CONSTANT THAT IS A LENGTH
                    LENGTHB  DC    A(L’FIELDB)        CREATE AN ADDRESS CONSTANT THAT IS A LENGTH
                    BLANK    DC    C’ ’
 
The above code copies 1000 X’s from FIELDB into FIELDA.  Since FIELDA was larger than FIELDB, the last 1000 bytes of
FIELDA are filled with the blank pad character.  If the length of FIELDA were equal to or smaller than the length of FIELDB, the
pad character would not be used.
 
   Bytes are transferred one at a time in a fashion similar to MVC, by MVCL.  As each byte is copied from source to target, the
even registers are incremented by one and the odd registers are decremented by one until one of the lengths in the odd registers
becomes zero.
 
   Consider the following scenarios with MVCL in which we are copying from field A to field B.  Assume the length of A is L1 and
the length of B is L2 .  Further assume A(A) and A(B) are the addresses of A and B.  Lengths are specified in decimal and we
assume a blank pad character in R7.
 
         Case 1:  L1 >  L2
 
           Before execution: 
                                                  R4                          R5                         R6                         R7
 

                                             A(A)                         1000                       A(B)                     40     500                    


 
 
 
           After execution:
 
                                                  R4                          R5                         R6                         R7
     
                                            A(A) + 1000                  0                       A(B) + 500            40     0

http://csc.columbusstate.edu/woolbright/MVCL.HTM[9/21/2011 4:22:53 PM]


Contents
 
 
        Case 2:  L1 = L2
 
           Before execution: 
                                                  R4                          R5                         R6                         R7
 

                                             A(A)                         1000                       A(B)                      1000                    


 
 
           After execution:
 
                                                  R4                         R5                        R6                          R7
     
                                            A(A) + 1000                  0                       A(B) + 1000          40       0
 
 
        Case 3:  L1 < L2
 
           Before execution: 
                                                  R4                          R5                         R6                         R7
 

                                             A(A)                         500                        A(B)                      1000                    


 
 
           After execution:
 
                                                  R4                         R5                         R6                         R7
     
                                            A(A) + 500                   0                       A(B) + 500            40     500
 
 
 
 
The pad byte is only used in case 1 where 500 blank characters are added to FIELDB.  In case 2, all 1000 characters of FIELDB
are copied to FIELDA.  In case 3, only the first 500 bytes of FEILDA are copied to FIELDB. 
 
   A destructive overlap occurs when the target and source fields overlap and the address of the source is lower than the address
of the target.  This is illustrated below.
 

  
   MVCL detects destructive overlap conditions and prevents any bytes from being moved.  Instead, MVCL sets the condition code
to indicate destructive overlap.  This condition can be tested with BO.
 
   MVCL sets the condition code to 0 (equal) if L1 = L2, to 1 (low) if L1 < L2, to 2 (high) if L1 > L2, and 3 (overflow) if no bytes are
moved due to destructive overlap.
 

http://csc.columbusstate.edu/woolbright/MVCL.HTM[9/21/2011 4:22:53 PM]


Contents

 
   You can use MVCL to blank out a target field by setting the length of the source to 0.  This forces the pad character to be copied
to each byte of the source:
 
                         LA   R8,TARGET
                         L    R9,TARLEN
                         LA   R4,SOURCE         SOURCE DOESN’T PARTICIPATE
                         LA   R5,0              SET THE LENGTH OF SOURCE TO 0
                         ICM  R5,B’1000’,BLANK  SET PAD BY TO A BLANK
                         MVCL R8,R4             COPY BLANKS
 
 
 
 

It is often difficult to find four available registers when coding MVCL.  A simple solution to this problem is to store four
consecutive registers in a save area before using MVCL and restore them afterwards:
                                                
                    STM   R4,R7,SAVE4
                    (use MVCL here…)
                    LM    R4,R7,SAVE4
                    …
           SAVE4    DS    4F              FOUR FULLWORDS FOR R4,R5,R6, AND R7
 
Use length attributes for the lengths of the source and target fields:
 
                      LENGTHA  DC    A(L’FIELDA)     TURN THE LENGTH INTO A FULLWORD “ADDRESS”  
                           

http://csc.columbusstate.edu/woolbright/MVCL.HTM[9/21/2011 4:22:53 PM]


mvi
Contents

 
 
   MVI is used to move a one byte immediate constant to a field in storage.  Operand 1 denotes the field in main storage, while the
second operand is coded as a self-defining term that gets assembled as a one byte immediate constant (II 2 ) in the second byte
of the object code.  Only the first byte of Operand 1 is affected by the move. 
 
   As an example, consider the following code,
 
                    MVI  FIELDA,X’C1’
                    ...
             FIELDA DC   X’123456’
 
After execution, FIELDA contains X’C13456’.  Only the first byte of the field is altered by the immediate instruction.    
 
The following example illustrates how an MVI instruction might be processed by the assembler.
 
     LOC      OBJECT CODE
 
 000F12  92F4C044                   MVI    CUSTCODE,C’4’  
                                    ...
 001028                CUSTCODE     DS    CL1
 
In the example above, the op-code for MVI is x’92’,  the self-defining term C’4’ is assembled as the one byte hexadecimal constant
x’F4’, and CUSTCODE is translated into the base/displacement address C044.
 
 

          Some Unrelated MVI’s:


 
   J        DC    C’ABC’
 
            MVI   J,C’X’  J = C’XBC’
            MVI   J,C’B’  J = C’BBC’
            MVI   J,C’5’  J = C’5BC’
            MVI   J,X’F5’ J = C’5BC’
            MVI   J,197   J = C’5BC’
            MVI   J,=C’5’ ASSEMBLY ERROR - OPERAND 2 NOT A SELF-DEFINING
                          TERM
            MVI   J(1),X’C5’  ASSEMBLY ERROR - LENGTH SPECIFICATION NOT
                              ALLOWED IN OPERAND 1

http://csc.columbusstate.edu/woolbright/MVI.HTM[9/21/2011 4:22:54 PM]


mvn
Contents

 
   MVN perfoms in a way that is analagous to MVC.  While MVC works on entires bytes, MVN only processes the numeric parts
(rightmost 4 bits) of the bytes it references.  The purpose of a move numeric instruction is to move the numeric parts of a
consecutive collection of bytes from one location in memory to another location.  As you can see from the instruction format above,
the instruction carries with it  the number of bytes to be copied (LL1 ), as well as the beginning addresses of the source
(B2 D 2 D 2 D 2 ) and target (B1 D 1 D 1 D 1 ) fields.  Notice that the instruction does not specifiy the ending addresses of either field - the
instruction is no respecter of fields.  MVN copies the numeric parts of LL 1 + 1 consecutive bytes from the storage location
designated by B2 D 2 D 2 D 2  to the storage location designated by B1 D 1 D 1 D 1 .
  
   The length (LL1 ) determines the number of “half-bytes” which will be copied.  The length is usually determined implicitly from the
length of operand 1 but the programmer can provide an explicit length.   Consider the two example MVN’s below,
 
     Object code                            Assembler code
 
                   FIELDA    DS        CL8
                   FIELDB    DS        CL5
                             ...     
  D107C008C010               MVN     FIELDA,FIELDB     Implicit length
  D102C008C010               MVN     FIELDA(3),FIELDB  Explicit length
 
In the first example, the length implicitly defaults to 8, the length of FIELDA.  In the second example, the length is explicitly 3.
Notice that the assembled length (LL1 ) is one less than the implicit or explicit length.  This can be seen in the object code above
where  the assembled lengths are x’07’ and x’02’.
 
   The copying operation is usually straightforward, but can be more complicated by overlapping the source and target fields.  Keep
in mind that the copy is made one byte at a time.  Consider the following examples,
 
     Object code                        Assembler code
 
                ONE       DC    C’1’        ONE = X’F1’
                FIELDA    DC    CL3’ABC’    FIELDA = X’C1C2C3’
                FIELDB    DC    XL3’123456’ FIELDB = X’123456’
...     
  D102C008C00B            MVN   FIELDA,FIELDB After FIELDA = X’C2C4C6’
  D102C00EC008            MVN   FIELDB,FIELDA After FIELDB = X’113253’  
  D102C008C007            MVN   FIELDA,ONE    After FIELDA = X’C1C1C1’  
 
In the first MVN above, 3 consecutive numeric half-bytes in FIELDB are simply copied to the numeric portions of  FIELDA.  The
half-bytes are copied, one at a time moving left to right within both operands.  In the second example, 3 consecutive bytes are
copied into FIELDB (implicit length = 3) from FIELDA. The third MVN is complicated by the fact that the source and target fields
overlap.  We will examine the third move in some detail.
 

http://csc.columbusstate.edu/woolbright/MVN.HTM[9/21/2011 4:22:55 PM]


mvn
Contents

 
 
 

          Some Unrelated MVN’s:


 
      A         DC    X’123456’
   B         DC    X’ABCDEF’    
   C         DC    X’A1B2’
                   ...             Result:
             MVN   A,B            A = X’1B3D5F’  B = X’ABCDEF’
             MVN   A+1,B          A = X’123B5D’  B = X’AFCDEF’
             MVN   A+1(2),B       A = X’123B5D’  B = X’ABCDEF’
             MVN   B,=X’D1E2’     B = X’A1C2E?’  One byte copied from
                                                 the literal pool
             MVN   B,B+1          B = ’ADCFE1’   Left shift
             MVN   B+1(2),B       B = ’ABCBEB’   1st byte is propagated
             MVN   C,A            C = ’A2B4’     A = X’123456’  
             MVN   A(L’C),C       A = ’113256’ Explicit Length attribute                 
             MVN   A(1000),B    Assembly Error - max length is 256 bytes
             MVN   A,B(20)      Assembly Error - Op-1 determines length
 
 
 
 

 
1.  Pay attention to the lengths of the fields involved in any MVN statement.  If the target field is longer than the source field, bytes
following the source may be transferred.  If the target field is shorter than the source field, bytes in the source may may be
truncated.
 
 

http://csc.columbusstate.edu/woolbright/MVN.HTM[9/21/2011 4:22:55 PM]


mvz
Contents

 
   MVZ perfoms in a way that is analagous to MVC.  While MVC works on entires bytes, MVZ only processes the zoned parts
(leftmost 4 bits) of the bytes it references.  The purpose of a move zones instruction is to move the zoned parts of a consecutive
collection of bytes from one location in memory to another location.  As you can see from the instruction format above, the
instruction carries with it  the number of bytes to be copied (LL1 ), as well as the beginning addresses of the source (B2 D 2 D 2 D 2 )
and target (B1 D 1 D 1 D 1 ) fields.  Notice that the instruction does not specifiy the ending addresses of either field - the instruction is
no respecter of fields.  MVZ copies the zoned parts of LL 1 + 1 consecutive bytes from the storage location designated by
B2 D 2 D 2 D 2  to the storage location designated by B1 D 1 D 1 D 1 .
  
   The length (LL1 ) determines the number of “half-bytes” which will be copied.  The length is usually determined implicitly from the
length of operand 1 but the programmer can provide an explicit length.   Consider the two example MVZ’s below,
 
     Object code                            Assembler code
 
                   FIELDA    DS        CL8
                   FIELDB    DS        CL5
                             ...     
  D307C008C010               MVZ     FIELDA,FIELDB     Implicit length
  D302C008C010               MVZ     FIELDA(3),FIELDB  Explicit length
 
In the first example, the length implicitly defaults to 8, the length of FIELDA.  In the second example, the length is explicitly 3.
Notice that the assembled length (LL1 ) is one less than the implicit or explicit length.  This can be seen in the object code above
where  the assembled lengths are x’07’ and x’02’.
 
   The copying operation is usually straightforward, but can be more complicated by overlapping the source and target fields.  Keep
in mind that the copy is made one byte at a time.  Consider the following examples,
 
     Object code                        Assembler code
 
                ONE       DC    C’1’        ONE = X’F1’
                FIELDA    DC    CL3’ABC’    FIELDA = X’C1C2C3’
                FIELDB    DC    XL3’123456’ FIELDB = X’123456’
...     
  D302C008C00B            MVZ   FIELDA,FIELDB After FIELDA = X’113253’
  D302C00EC008            MVZ   FIELDB,FIELDA After FIELDB = X’C2C4C6’  
  D302C008C007            MVZ   FIELDA,ONE    After FIELDA = X’F1F2F3’  
 
In the first MVZ above, 3 consecutive zoned half-bytes in FIELDB are simply copied to the zoned portions of  FIELDA.  The half-
bytes are copied, one at a time moving left to right within both operands.  In the second example, 3 consecutive bytes are copied
into FIELDB (implicit length = 3) from FIELDA. The third MVZ is complicated by the fact that the source and target fields overlap. 
We will examine the third move in some detail.
 

http://csc.columbusstate.edu/woolbright/MVZ.HTM[9/21/2011 4:22:56 PM]


mvz
Contents

 
 
 

          Some Unrelated MVZ’s:


 
      A         DC    X’123456’
   B         DC    X’ABCDEF’    
   C         DC    X’A1B2’
                   ...             Result:
             MVZ   A,B            A = X’A2C4E6’  B = X’ABCDEF’
             MVZ   A+1,B          A = X’12A4C6’  B = X’EBCDEF’
             MVZ   A+1(2),B       A = X’12A4C6’  B = X’ABCDEF’
             MVZ   B,=X’D1E2’     B = X’DBED?F’  One byte copied from
                                                 the literal pool
             MVZ   B,B+1          B = ’CBEDAF’   Left shift
             MVZ   B+1(2),B       B = ’ABADAF’   1st byte is propagated
             MVZ   C,A            C = ’1132’     A = X’123456’ 
             MVZ   A(L’C),C       A = ’A2B456’ Explicit Length attribute                  
             MVZ   A(1000),B    Assembly Error - max length is 256 bytes
             MVZ   A,B(20)      Assembly Error - Op-1 determines length
 
 
 
 

 
1.  Pay attention to the lengths of the fields involved in any MVZ statement.  If the target field is longer than the source field, bytes
following the source may be transferred.  If the target field is shorter than the source field, bytes in the source may may be
truncated.
 
 

http://csc.columbusstate.edu/woolbright/MVZ.HTM[9/21/2011 4:22:56 PM]


and
Contents

 
 
   The And instruction performs a logical bit by bit “and” between a register and a fullword in memory.  Operand 1, the target,  is a
register and Operand 2, the source, specifies a fullword in memory.  The fullword in memory is anded internally with the fullword in
the register and the result is placed in the register.  The fullword in memory is not changed.  The table below shows the results of
“anding” two bits together.
 
                                                      Bit 1      Bit 2    Result
                                                         0           0            0
                                                         0           1            0
                                                         1           0            0
                                                         1           1            1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Ands


 
              R4 =  X’FFFFFFFF’   ALL 1’S
              R5 =  X’00000000’   ALL 0’S
              R6 =  X’0000148C’   00000000000000000001010010001100
  
              FIELD1  DC   X’0000148C’
              FIELD2  DC   X’00000000’
              FIELD3  DC   X’FFFFFFFF’
              FIELD4  DC   X’12345678’
 
              N    R4,FIELD1    R4 = X’0000148C’ Condition Code = 1
              N    R4,FIELD2    R4 = X’00000000’ Condition Code = 0
              N    R4,FIELD3    R4 = X’FFFFFFFF’ Condition Code = 1
              N    R4,FIELD4    R4 = X’12345678’ Condition Code = 1
              N    R5,FIELD1    R5 = X’00000000’ Condition Code = 0
              N    R5,FIELD2    R5 = X’00000000’ Condition Code = 0
              N    R5,FIELD3    R5 = X’00000000’ Condition Code = 0
              N    R5,FIELD4    R5 = X’00000000’ Condition Code = 0
              N    R6,FIELD1    R6 = X’0000148C’ Condition Code = 1
              N    R6,FIELD2    R6 = X’00000000’ Condition Code = 0
              N    R6,FIELD3    R6 = X’0000148C’ Condition Code = 1
              N    R6,FIELD4    R6 = X’00001408’ Condition Code = 1

http://csc.columbusstate.edu/woolbright/AND.HTM[9/21/2011 4:22:57 PM]


AND CHAR
Contents

 
 
   The And Character instruction performs a logical bit by bit “and” between two fields in memory. Operand 1, the target,  is a
memory field and Operand 2, the source, also specifies a storage location in memory.  The number of characters which participate
in the operation is determined by the first operand, and as a result, is limited to 256 bytes.  The storage fields are “and-ed”
internally with the result placed in the target field. Typically, the source is unaffected, but can be altered by this operation if the
fields overlap.  The table below shows the results of “and-ing” two bits together.
 
                                                       Bit 1      Bit 2    Bit 1 and Bit 2
                                                          0           0                  0
                                                          0           1                  0
                                                          1           0                  0
                                                          1           1                  1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated And Characters


 
              FIELD1  DC   X’0001020304’
              FIELD2  DC   X’FFFFFF’
              FIELD3  DC   C’ABC’
              FIELD4  DC   X’000000’
              FIELD5  DC   B’10101111’
              FIELD6  DC   B’10001001’
 
     NC    FIELD1,FIELD1    FIELD1 = X’0001020304’ Condition Code = 1
     NC    FIELD2,FIELD1    FIELD2 = X’000102’     Condition Code = 1
     NC    FIELD3,FIELD1    FIELD3 = X’000102’     Condition Code = 1
     NC    FIELD2,FIELD3    FIELD2 = X’C1C2C3’     Condition Code = 1
     NC    FIELD4,FIELD4    FIELD4 = X’000000’     Condition Code = 0
     NC    FIELD3,FIELD4    FIELD3 = X’000000’     Condition Code = 0
     NC    FIELD1+2,FIELD3  FIELD1 = X’0001000200’ Condition Code = 1
                            FIELD2 = X’0000FFFF’
     NC    FIELD1(3),FIELD2 FIELD1 = X’0001020304’ Condition Code = 1
     NC    FIELD5,FIELD6    FIELD5 = B’10001001’   Condition Code = 1

http://csc.columbusstate.edu/woolbright/ANDCHAR.HTM[9/21/2011 4:22:58 PM]


AND IMMEDIATE
Contents

                                                  
  
 
   The And Immediate instruction performs a logical bit by bit “and” between a byte in memory  and an immediate constant. 
Operand 1, the target,  is a byte in memory and Operand 2, the source, specifies the immediate constant.  The byte in memory is
“and-ed” internally with the immediate constant and contains the final result.  The immediate constant is not changed.  The table
below shows the results of “anding” two bits together.
 
                                                 Bit 1      Bit 2    Bit 1 and Bit 2
                                                    0           0                  0
                                                    0           1                  0
                                                    1           0                  0
                                                    1           1                  1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated And Immediates


 
              BYTE1  DC   X’00’
              BYTE2  DC   X’FF’
              BYTE3  DC   X’C3’
 
       NI    BYTE1,X’12’         BYTE1 = X’00’    Condition Code = 0
       NI    BYTE1,X’FF’         BYTE1 = X’00’    Condition Code = 0
       NI    BYTE1,C’A’          BYTE1 = X’00’    Condition Code = 0
       NI    BYTE1,B’11110000’   BYTE1 = X’00’    Condition Code = 0
       NI    BYTE2,X’12’         BYTE2 = X’12’    Condition Code = 1
       NI    BYTE2,X’FF’         BYTE2 = X’FF’    Condition Code = 1
       NI    BYTE2,C’A’          BYTE2 = X’C1’    Condition Code = 1
       NI    BYTE2,B’11110000’   BYTE2 = X’F0’    Condition Code = 1
       NI    BYTE3,X’12’         BYTE3 = X’02’    Condition Code = 1
       NI    BYTE3,X’FF’         BYTE3 = X’C3’    Condition Code = 1
       NI    BYTE3,C’A’          BYTE3 = X’C1’    Condition Code = 1
       NI    BYTE3,B’11110000’   BYTE3 = X’C0’    Condition Code = 1

http://csc.columbusstate.edu/woolbright/ANDIMM.HTM[9/21/2011 4:22:59 PM]


and register
Contents

                                                              
 
   The And Register instruction performs a logical bit by bit “and” between two registers.  Operand 1, the target,  is a register and
Operand 2, the source, also specifies a register.  The fullword in Operand 1 is “and-ed” internally with the fullword in Operand 2, 
and the result is placed in Operand 1.  The table below shows the results of “and-ing” two bits together.
 
                                                       Bit 1      Bit 2    Bit 1 and Bit 2
                                                          0           0                  0
                                                          0           1                  0
                                                          1           0                  0
                                                          1           1                  1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated And Registers


 
              R4 =  X’FFFFFFFF’   ALL 1’S
              R5 =  X’00000000’   ALL 0’S
              R6 =  X’0000148C’   00000000000000000001010010001100
              R7 =  X’000014AB’   00000000000000000001010010101011
 
              NR   R4,R4    R4 = X’FFFFFFFF’ Condition Code = 1
              NR   R4,R5    R4 = X’00000000’ Condition Code = 0
              NR   R4,R6    R4 = X’0000148C’ Condition Code = 1
              NR   R4,R7    R4 = X’000014AB’ Condition Code = 1
              NR   R5,R6    R5 = X’00000000’ Condition Code = 0
              NR   R5,R7    R5 = X’00000000’ Condition Code = 0
              NR   R6,R7    R6 = X’00001488’ Condition Code = 1
              NR   R7,R7    R7 = X’000014AB’ Condition Code = 1

http://csc.columbusstate.edu/woolbright/ANDREG.HTM[9/21/2011 4:22:59 PM]


or
Contents

 
 
   The Or instruction performs a logical bit by bit “or” between a register and a fullword in memory.  Operand 1, the target,  is a
register and Operand 2, the source, specifies a fullword in memory.  The fullword in memory is or-ed internally with the fullword in
the register and the result is placed in the register.  The fullword in memory is not changed.  The table below shows the results of
“or-ing” two bits together.
 
                                                       Bit 1      Bit 2    Result
                                                          0           0            0
                                                          0           1            1
                                                          1           0            1
                                                          1           1            1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Ors


 
              R4 =  X’FFFFFFFF’   ALL 1’S
              R5 =  X’00000000’   ALL 0’S
              R6 =  X’0000148C’   00000000000000000001010010001100
  
              FIELD1  DC   X’0000148C’
              FIELD2  DC   X’00000000’
              FIELD3  DC   X’FFFFFFFF’
              FIELD4  DC   X’12345678’
 
              O    R4,FIELD1    R4 = X’FFFFFFFF’ Condition Code = 1
              O    R4,FIELD2    R4 = X’FFFFFFFF’ Condition Code = 1
              O    R4,FIELD3    R4 = X’FFFFFFFF’ Condition Code = 1
              O    R4,FIELD4    R4 = X’FFFFFFFF’ Condition Code = 1
              O    R5,FIELD1    R5 = X’0000148C’ Condition Code = 1
              O    R5,FIELD2    R5 = X’00000000’ Condition Code = 0
              O    R5,FIELD3    R5 = X’FFFFFFFF’ Condition Code = 1
              O    R5,FIELD4    R5 = X’12345678’ Condition Code = 1
              O    R6,FIELD1    R6 = X’0000148C’ Condition Code = 1
              O    R6,FIELD2    R6 = X’0000148C’ Condition Code = 1
              O    R6,FIELD3    R6 = X’FFFFFFFF’ Condition Code = 1
              O    R6,FIELD4    R6 = X’123456FC’ Condition Code = 1

http://csc.columbusstate.edu/woolbright/OR.HTM[9/21/2011 4:23:00 PM]


or character
Contents

 
 
   The Or Character instruction performs a logical bit by bit “or” between two fields in memory. Operand 1, the target,  is a memory
field and Operand 2, the source, also specifies a storage location in memory.  The number of characters which participate in the
operation is determined by the first operand, and as a result, is limited to 256 bytes.  The storage fields are or-ed internally with
the result placed in the target field. Typically, the source is unaffected, but can be altered by this operation if the fields overlap. 
The table below shows the results of “or-ing” two bits together.
 
                                                       Bit 1      Bit 2    Result
                                                          0           0            0
                                                          0           1            1
                                                          1           0            1
                                                          1           1            1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Or Characters


 
              FIELD1  DC   X’0001020304’
              FIELD2  DC   X’FFFFFF’
              FIELD3  DC   C’ABC’
              FIELD4  DC   X’000000’
 
     OC    FIELD1,FIELD1    FIELD1 = X’0001020304’ Condition Code = 1
     OC    FIELD2,FIELD1    FIELD2 = X’FFFFFF’     Condition Code = 1
     OC    FIELD3,FIELD1    FIELD3 = X’C1C3C3’     Condition Code = 1
     OC    FIELD2,FIELD3    FIELD2 = X’FFFFFF’     Condition Code = 1
     OC    FIELD4,FIELD4    FIELD4 = X’000000’     Condition Code = 0
     OC    FIELD3,FIELD4    FIELD3 = X’C1C2C3’     Condition Code = 1
     OC    FIELD1+2,FIELD3  FIELD1 = X’0001C3C3C7’ Condition Code = 1
     OC    FIELD1(3),FIELD2 FIELD1 = X’FFFFFF0304’ Condition Code = 1

http://csc.columbusstate.edu/woolbright/ORCHAR.HTM[9/21/2011 4:23:01 PM]


AND IMMEDIATE
Contents

                                                  
  
 
   The Or Immediate instruction performs a logical bit by bit “or” between a byte in memory and an immediate constant.  Operand 1,
the target,  is a byte in memory and Operand 2, the source, specifies the immediate constant.  The byte in memory is or-ed
internally with the immediate constant and contains the final result.  The immediate constant is not changed.  The table below
shows the results of “or-ing” two bits together.
 
                                                 Bit 1      Bit 2    Result
                                                    0           0            0
                                                    0           1            1
                                                    1           0            1
                                                    1           1            1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Or Immediates


 
              BYTE1  DC   X’00’
              BYTE2  DC   X’FF’
              BYTE3  DC   X’C3’
 
       OI    BYTE1,X’12’         BYTE1 = X’12’    Condition Code = 1
       OI    BYTE1,X’FF’         BYTE1 = X’FF’    Condition Code = 1
       OI    BYTE1,C’A’          BYTE1 = X’C1’    Condition Code = 1
       OI    BYTE1,B’11110000’   BYTE1 = X’F0’    Condition Code = 1
       OI    BYTE1,B’00000000’   BYTE1 = X’00’    Condition Code = 0
       OI    BYTE2,X’12’         BYTE2 = X’FF’    Condition Code = 1
       OI    BYTE2,X’FF’         BYTE2 = X’FF’    Condition Code = 1
       OI    BYTE2,C’A’          BYTE2 = X’FF’    Condition Code = 1
       OI    BYTE2,B’11110000’   BYTE2 = X’FF’    Condition Code = 1
       OI    BYTE3,X’12’         BYTE3 = X’D3’    Condition Code = 1
       OI    BYTE3,X’FF’         BYTE3 = X’FF’    Condition Code = 1
       OI    BYTE3,C’A’          BYTE3 = X’C3’    Condition Code = 1
       OI    BYTE3,B’11110000’   BYTE3 = X’F3’    Condition Code = 1

http://csc.columbusstate.edu/woolbright/ORIMM.HTM[9/21/2011 4:23:02 PM]


OR REGISTER
Contents

                                                              
 
   The Or Register instruction performs a logical bit by bit “or” between two registers.  Operand 1, the target,  is a register and
Operand 2, the source, also specifies a register.  The fullword in Operand 1 is or-ed internally with the fullword in Operand 2, and
the result is placed in Operand 1.  The table below shows the results of “or-ing” two bits together.
 
                                                       Bit 1      Bit 2    Result
                                                          0           0            0
                                                          0           1            1
                                                          1           0            1
                                                          1           1            1
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Or Registers


 
              R4 =  X’FFFFFFFF’   ALL 1’S
              R5 =  X’00000000’   ALL 0’S
              R6 =  X’0000148C’   00000000000000000001010010001100
              R7 =  X’000014AB’   00000000000000000001010010101011
              R8 =  X’1A3359CF’   00011010001100110101100111001111
              R9 =  X’8CF4594A’   10001100111101000101100101001010
 
              OR   R4,R4    R4 = X’FFFFFFFF’ Condition Code = 1
              OR   R4,R5    R4 = X’FFFFFFFF’ Condition Code = 1
              OR   R4,R6    R4 = X’FFFFFFFF’ Condition Code = 1
              OR   R4,R7    R4 = X’FFFFFFFF’ Condition Code = 1
              OR   R5,R5    R5 = X’00000000’ Condition Code = 0
              OR   R5,R6    R5 = X’0000148C’ Condition Code = 1
              OR   R5,R7    R5 = X’000014AB’ Condition Code = 1
              OR   R6,R7    R6 = X’000014AF’ Condition Code = 1
              OR   R7,R7    R7 = X’000014AB’ Condition Code = 1
              OR   R8,R9    R8 = X’9EF759CF’ Condition Code = 1

http://csc.columbusstate.edu/woolbright/ORREG.HTM[9/21/2011 4:23:02 PM]


pack
Contents

 
   PACK is a SS 2 instruction which is designed to convert data from character or zoned decimal format to packed decimal format. 
The operation proceeds by transferring the contents of operand 2 to operand 1.  Bytes in operand 1 and 2 are referenced from
right to left within the fields.  The rightmost byte of operand 2 is referenced first, and the zone and numeric parts of the byte are
reversed and placed in the rightmost byte of operand 1.  Then the numeric parts of the next two bytes of operand 2 are placed in
the next byte of operand 1.  This process continues by “packing” the numeric parts of operand 2 into operand 1, always moving
from right to left, taking two bytes and packing into one byte.  The example below illustrates this idea.  The first field, AZONED,
contains zoned decimal data, while the second field, APK, shows the results of executing “PACK    APK,AZONED”.  We assume
the following definitions,
 
                       AZONED     DC    ZL7’7893023’
                       APK        DS    PL4
                       ...
                       PACK       APK,AZONED
 

 
  Since PACK is SS 2 , each operand contributes a 4-bit length which is stored in the second byte of the object code as pictured at
the top of this page.  The maximum length in the object code is B’1111’ = 15.  Since the assembler always decrements lengths by
1, packed fields are limited to a maximum of 16 bytes.  It is also important to note that the lengths of both fields are used to
execute this instruction.  For instance, if APK was defined as PL3, the high-order digits in the packed field (those on the left) are
truncated.
 
                       PACK    APK,AZONE

On the other hand,  if there are too few bytes in operand 2, zeros will be padded on the left in operand 1 as illustrated below. 
Assume APK was defined as PL6.
 
                       PACK    APK,AZONED   
 

http://csc.columbusstate.edu/woolbright/PACK.HTM[9/21/2011 4:23:04 PM]


pack
Contents

 
 
 

          Some unrelated PACK’s:


 
 A          DC      C’12345’      = X’F1F2F3F4F5’
 B          DC      Z’1234’       = X’F1F2F3C4’    
 C          DC      C’ABC’        = X’C1C2C3’
 D          DC      X’12ABCDEF’   = X’12ABCDEF’
 P          DS      PL3
 Q          DS      PL2
 R          DS      PL4
 
            PACK    P,A        P = X’12345F’  SIGN UNCHANGED
            PACK    Q,A        Q = X’345F’  LEFT TRUNCATION
            PACK    R,A        R = X’0012345F’  PAD ZEROES
            PACK    P,B        P = X’01234C’ 
            PACK    Q,B        Q = X’234C’   LEFT TRUNCATION
            PACK    R,B        R = X’0001234C’ PAD ZEROES
            PACK    P,C        P = X’00123C’  PACK WILL PROCESS
                                              ANY DATA WITHOUT
                                              ABEND
            PACK    P,D        P = X’02BDFE’  IT WILL PACK...
                      

 
1.  PACK works with any kind of data.  That does not mean that you will compute correct results.  It simply means that the program
will not abend because of the data contents in a field you are packing.  Packed decimal problems show up when arithmetic
instructions are executed.

http://csc.columbusstate.edu/woolbright/PACK.HTM[9/21/2011 4:23:04 PM]


SUBTRACT
Contents

 
 
   The Subtract instruction performs 2’s complement binary subtraction.  Operand 1 is a register containing a fullword integer. 
Operand 2 specifies a fullword in memory.  The fullword in memory is subtracted from the fullword in the register and the result
remains in the register.  The fullword in memory is not changed.  Consider the following example,    
 
                            S    R9,AFIELD       
 

   The contents of the fullword “AFIELD”, x’0000001F’ = 31, are subtracted from register 9 which contains x’00000031’ = 49.  The
difference is 18 = x’00000012’ destroying the previous value in R9.  The fullword in memory is unchanged by this operation.
 
   Since S is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing.
 

          Some Unrelated Adds


 
              R4 =  X’FFFFFFD5’  -43 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
  
              DOG   DC   F’35’
              CAT   DC   F’4’
 
              S    R4,=F’20’    R4 = X’FFFFFFC1’ = -63
              S    R5,=F’-20’   R5 = X’0000003C’ = +60
              S    R6,=F’20’    R6 = X’FFFFFFF0’ = -16
              S    R6,=F’-5’    R6 = X’00000009’ = +9
              S    R6,CAT       R6 = X’00000000’ =  0
              S    R5,DOG       R5 = X’00000005’ = +5
              S    R6,DOG(R6)   R6 = X’00000000’  INDEXING IS ALLOWED

http://csc.columbusstate.edu/woolbright/SUBTRACT.HTM[9/21/2011 4:23:05 PM]


shift left algebraic
Contents

 
   SLA is used to shift the 32 bits in the register specified by Operand 1 to the left.  The number of bits that are shifted is indicated
by Operand 2.  The second operand address is not used to address data; instead, the base/displacement address is computed
and the rightmost 6 bits are treated as a binary integer which represents the number of bits to be shifted.  We will call this value
the “shift factor”.  This leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SLA  R9,5
 
In the above shift, the second operand, 5, is treated as a base/displacement address where 5 is the displacement and the base
register is omitted.  The effective address is 5. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 5, and so the bits in register 9 are shifted to the left by 5 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SLL  R9,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting algebraically, bits shifted out on the left are lost, while 0’s replace bits on the right.  The sign bit in Operand 1
remains fixed, preserving the sign of the integer.  If one or more bits unlike the sign bit are shifted out on the left, an overflow
occurs and the condition code is set to 3.  This will cause a program interruption if the fixed-point overflow mask is set to 1. (See
SPM.) Otherwise the condition code can be tested using BO.
 
   The condition code is set by this instruction in all cases:
 
 
 
 
                                Condition Code             Meaning                                     Test With
 
                    0            Result = 0 (No overflow)   BZ, BE
                    1            Result < 0 (No overflow)   BL, BM
                    2            Result > 0 (No overflow)   BH, BP
                    3            Overflow                   BO
 
   Consider the following instruction.
 
                            SLA  R8,3
 
This instruction represents a left algebraic shift of register 8 using a shift factor of 3.  The shift factor has been coded directly.  As a

http://csc.columbusstate.edu/woolbright/SLA.HTM[9/21/2011 4:23:05 PM]


shift left algebraic
Contents
result, 3 bits, 111, are shifted out of the register on the left leaving the sign bit fixed.  Vacated bit positions on the right are
replaced by 0’s.  This is illustrated in the diagram below.  The condition code is set to 1, indicating that the resulting binary integer
is negative.
 
 

   This instruction has an RS format but the 4 low-order bits of the second byte of the object code are unused.
 

             Some Unrelated SLA’s


 
               R5 = B’11111111111111111111111111111111’
               R6 = B’00001111000011110000111100001111’
        
  SLA  R5,1     R5 = B’11111111111111111111111111111110’  Cond.Code = 1
  SLA  R5,2     R5 = B’11111111111111111111111111111100’  Cond.Code = 1
  SLA  R5,3     R5 = B’11111111111111111111111111111000’  Cond.Code = 1
  SLA  R5,31    R5 = B’10000000000000000000000000000000’  Cond.Code = 1
  SLA  R5,32    R5 = B’10000000000000000000000000000000’  Cond.Code = 3
                                                          (Overflow)
  SLA  R6,2     R6 = B’00111100001111000011110000111100’  Cond.Code = 2
  SLA  R6,4     R6 = B’01110000111100001111000011110000’  Cond.Code = 3
                                                          (Overflow)
 
  L    R9,=F’3’
  SLA  R5,0(R9) R5 = B’11111111111111111111111111111000’
 
  L    R3,=F’5’
  SLA  R5,0(R3) R5 = B’11111111111111111111111111100000’
 

1)  Shifting a binary number to the left one digit is equivalent to multiplying it by 2.  Using SLA, it is a simple matter to multiply by
powers of 2.  For instance, to multiply by 2 5 , shift left 5 digits.

http://csc.columbusstate.edu/woolbright/SLA.HTM[9/21/2011 4:23:05 PM]


shift left double algebraic
Contents

 
   Operand 1 specifies the even register of an even-odd consecutive pair of general purpose registers.  For instance R4 would
represent registers 4 and 5, while R8 would represent registers 8 and 9.  SLDA is used to shift the 64 bits in the even-odd pair as
if they comprised a single register.  The shift is to the left.  The number of bits that are shifted is indicated by Operand 2.  The
second operand address is not used to address data; instead, the base/displacement address is computed and the rightmost 6 bits
are treated as a binary integer which represents the number of bits to be shifted.  We will call this value the “shift factor”.  This
leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SLDA  R8,5
 
In the above shift, the second operand, 5, is treated as a base/displacement address where 5 is the displacement and the base
register is omitted.  The effective address is 5. (See Explicit Addressing.)  When represented as an address, the rightmost 6 bits
still represent the number 5, and so the bits in registers 8 and 9 are shifted to the left by 5 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SLDA  R8,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting algebraically, bits shifted out on the left are lost, while 0’s replace bits on the right.  The sign bit in Operand 1
remains fixed, preserving the sign of the integer.  If one or more bits unlike the sign bit are shifted out on the left, an overflow
occurs and the condition code is set to 3.  This will cause a program interruption if the fixed-point overflow mask is set to 1. (See
SPM.) Otherwise the condition code can be tested using BO.
 
   The condition code is set by this instruction in all cases:
 
 
 
 
                                Condition Code             Meaning                                     Test With
 
                   0            Result = 0 (No overflow)   BZ, BE
                   1            Result < 0 (No overflow)   BL, BM
                   2            Result > 0 (No overflow)   BH, BP
                   3            Overflow                   BO
 
   Consider the following instruction.
 

http://csc.columbusstate.edu/woolbright/SLDA.HTM[9/21/2011 4:23:06 PM]


shift left double algebraic
Contents
                            SLDA  R8,3
 
This instruction represents a left algebraic shift of registers 8 and 9 using a shift factor of 3.  The shift factor has been coded
directly.  As a result, 3 bits, 111, are shifted out of the register on the left leaving the sign bit fixed.  Vacated bit positions on the
right are replace by 0’s.  This is illustrated in the diagram below.  The condition code is set to 1, indicating that the resulting 64-bit
binary integer is negative.
 
 

   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SLDA’s


 
               R6 = B’11111111111111111111111111111111’
               R7 = B’00001111000011110000111100001111’
        
  SLDA  R6,1     R6 = B’11111111111111111111111111111110’  Cond.Code = 1
                 R7 = B’00011110000111100001111000011110’
  SLDA  R6,2     R6 = B’11111111111111111111111111111100’  Cond.Code = 1
                 R7 = B’00111100001111000011110000111100’
  SLDA  R6,3     R6 = B’11111111111111111111111111111000’  Cond.Code = 1
                 R7 = B’01111000011110000111100001111000’
 
  SLDA  R6,31    R6 = B’10000111100001111000011110000111’  Cond.Code = 1
                 R7 = B’10000000000000000000000000000000’
 
  SLDA  R6,32    R6 = B’10001111000011110000111100001111’  Cond.Code = 3
                 R7 = B’00000000000000000000000000000000’  (Overflow)
 
 
  L    R9,=F’3’
  SLDA R6,0(R9)  R6 = B’11111111111111111111111111111000’
                 R7 = B’01111000011110000111100001111000’
 

1)  Shifting a binary number to the left one digit is equivalent to multiplying it by 2.  Using SLDA, it is a simple matter to multiply by
powers of 2.  For instance, to multiply by 2 5 , shift left 5 digits.

http://csc.columbusstate.edu/woolbright/SLDA.HTM[9/21/2011 4:23:06 PM]


shift left double logical
Contents

 
   Operand 1 specifies the even register of an even-odd consecutive pair of general purpose registers.  For instance R4 would
represent registers 4 and 5, while R8 would represent registers 8 and 9.  SLDL is used to shift the 64 bits in the even-odd pair as if
they comprised a single register.  The shift is to the left.  The number of bits that are shifted is indicated by Operand 2.  The
second operand address is not used to address data; instead, the base/displacement address is computed and the rightmost 6 bits
are treated as a binary integer which represents the number of bits to be shifted.  We will call this value the “shift factor”.  This
leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SLDL  R8,5
 
In the above shift, the second operand, 5, is treated as a base/displacement address where 5 is the displacement and the base
register is omitted.  The effective address is 5. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 5, and so the bits in registers 8 and 9 are shifted to the left by 5 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SLDL R8,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting logically, bits shifted out on the left are lost, while 0’s replace bits on the right.
 
   Consider the following instruction.
 
                            SLDL  R8,6
 
This instruction represents a left shift of registers 8  and 9 using a shift factor of 6.  The shift factor has been coded directly.  As a
result, 6 bits, 111100, are shifted out of the register on the left.  Vacated bit positions on the right are replace by 0’s.  This is
illustrated in the diagram below.
 

http://csc.columbusstate.edu/woolbright/SLDL.HTM[9/21/2011 4:23:07 PM]


shift left double logical
Contents

   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SLDL’s


 
               R4 = B’11110000111111111111111111111111’
               R5 = B’00000000000000000000000000001111’
        
        SLDL  R4,1     R4 = B’11111111111111111111111111111110’
                       R5 = B’00000000000000000000000000011110’
        SLDL  R4,2     R4 = B’11111111111111111111111111111100’
                       R5 = B’00000000000000000000000000111100’
        SLDL  R4,31    R4 = B’10000000000000000000000000000111’
                       R5 = B’10000000000000000000000000000000’
        SLDL  R4,32    R4 = B’00000000000000000000000000001111’
                       R5 = B’00000000000000000000000000000000’
        SLDL  R4,4     R4 = B’00001111111111111111111111110000’
                       R5 = B’00000000000000000000000011110000’
 
        L     R9,=F’3’
        SLDL  R4,0(R9) R4 = B’10000111111111111111111111111000’
                       R5 = B’00000000000000000000000001111000’
        L    R3,=F’5’
        SLL  R4,0(R3)  R4 = B’00011111111111111111111111100000’
                       R5 = B’00000000000000000000000111100000’

http://csc.columbusstate.edu/woolbright/SLDL.HTM[9/21/2011 4:23:07 PM]


shift left logical
Contents

 
   SLL is used to shift the 32 bits in the register specified by Operand 1 to the left.  The number of bits that are shifted is indicated
by Operand 2.  The second operand address is not used to address data; instead, the base/displacement address is computed
and the rightmost 6 bits are treated as a binary integer which represents the number of bits to be shifted.  We will call this value
the “shift factor”.  This leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SLL  R9,5
 
In the above shift, the second operand, 5, is treated as a base/displacement address where 5 is the displacement and the base
register is omitted.  The effective address is 5. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 5, and so the bits in register 9 are shifted to the left by 5 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SLL  R9,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting logically, bits shifted out on the left are lost, while 0’s replace bits on the right.
 
   Consider the following instruction.
 
                            SLL  R8,6
 
This instruction represents a left shift of register 8 using a shift factor of 6.  The shift factor has been coded directly.  As a result, 6
bits, 111100, are shifted out of the register on the left.  Vacated bit positions on the right are replace by 0’s.  This is illustrated in
the diagram below.

http://csc.columbusstate.edu/woolbright/SLL.HTM[9/21/2011 4:23:08 PM]


shift left logical
Contents

   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SLL’s


 
               R5 = B’11111111111111111111111111111111’
               R6 = B’11110000111100001111000011110000’
        
          SLL  R5,1     R5 = B’11111111111111111111111111111110’
          SLL  R5,2     R5 = B’11111111111111111111111111111100’
          SLL  R5,3     R5 = B’11111111111111111111111111111000’
          SLL  R5,31    R5 = B’10000000000000000000000000000000’
          SLL  R5,32    R5 = B’00000000000000000000000000000000’
          SLL  R6,4     R6 = B’00001111000011110000111100000000’
 
          L    R9,=F’3’
          SLL  R5,0(R9) R5 = B’11111111111111111111111111111000’
 
          L    R3,=F’5’
          SLL  R5,0(R3) R5 = B’11111111111111111111111111100000’

http://csc.columbusstate.edu/woolbright/SLL.HTM[9/21/2011 4:23:08 PM]


shift right algebraic
Contents

 
   SRA is used to shift the 32 bits in the register specified by Operand 1 to the right.  The number of bits that are shifted is
indicated by Operand 2.  The second operand address is not used to address data; instead, the base/displacement address is
computed and the rightmost 6 bits are treated as a binary integer which represents the number of bits to be shifted.  We will call
this value the “shift factor”.  This leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SRA  R9,5
 
In the above shift, the second operand, 5, is treated as a base/displacement address where 5 is the displacement and the base
register is omitted.  The effective address is 5. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 5, and so the bits in register 9 are shifted to the right by 5 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SRA  R9,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting algebraically, bits shifted out on the right are lost, while bits equal to the sign bit replace vacated bits on the left. 
The sign bit in Operand 1 remains fixed, preserving the sign of the integer.
 
 
 
 
 
 
 
   The condition code is set by this instruction in all cases:
 
                                Condition Code             Meaning                   Test With
 
                    0            Result = 0       BZ, BE
                    1            Result < 0       BL, BM
                    2            Result > 0       BH, BP
 
   Consider the following instruction and the diagram below.
 
                            SRA  R8,3
 
This instruction represents a right algebraic shift of register 8 using a shift factor of 3.  The shift factor has been coded directly.  As

http://csc.columbusstate.edu/woolbright/SRA.HTM[9/21/2011 4:23:09 PM]


shift right algebraic
Contents
a result, 3 bits, 000, are shifted out of the register on the right.  Vacated bit positions on the left are replace by 1’s (the sign bit is
negative).  This is illustrated in the diagram below.  The condition code is set to 1, indicating that the resulting binary integer is
negative.
 
 

   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SRA’s


 
               R5 = B’11111111111111111111111111110000’
               R6 = B’00001111000011110000111100001111’
        
  SRA  R5,1     R5 = B’11111111111111111111111111111000’  Cond.Code = 1
  SRA  R5,2     R5 = B’11111111111111111111111111111100’  Cond.Code = 1
  SRA  R5,3     R5 = B’11111111111111111111111111111110’  Cond.Code = 1
  SRA  R5,4     R5 = B’11111111111111111111111111111111’  Cond.Code = 1
  SRA  R5,2     R5 = B’11111111111111111111111111111100’  Cond.Code = 1
  SRA  R6,4     R6 = B’00000000111100001111000011110000’  Cond.Code = 2
 
  L    R9,=F’3’
  SRA  R6,0(R9) R6 = B’00000001111000011110000111100001’  Cond.Code = 2
 
  L    R3,=F’5’
  SRA  R6,0(R3) R6 = B’00000000011110000111100001111000’  Cond.Code = 2
 

1)  Shifting a binary number to the right one digit is equivalent to dividing it by 2 (using integer arithmetic).  Using SRA, it is a
simple matter to divide by powers of 2.  For instance, to divide by 2 5 , shift right 5 digits.

http://csc.columbusstate.edu/woolbright/SRA.HTM[9/21/2011 4:23:09 PM]


shift right algebraic
Contents

 
   Operand 1 specifies the even register of an even-odd consecutive pair of general purpose registers.  For instance R4 would
represent registers 4 and 5, while R8 would represent registers 8 and 9.  SRDA is used to shift the 64 bits in the even-odd pair as
if they comprised a single register.  The shift is to the right.  The number of bits that are shifted is indicated by Operand 2.  The
second operand address is not used to address data; instead, the base/displacement address is computed and the rightmost 6 bits
are treated as a binary integer which represents the number of bits to be shifted.  We will call this value the “shift factor”.  This
leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SRDA  R8,5
 
In the above shift, the second operand, 5, is treated as a base/displacement address where 5 is the displacement and the base
register is omitted.  The effective address is 5. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 5, and so the bits in registers 8 and 9 are shifted to the right by 5 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SRDA R8,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting algebraically, bits shifted out on the right are lost, while bits equal to the sign bit replace vacated bits on the left. 
The sign bit in Operand 1 remains fixed, preserving the sign of the integer.
 
 
 
 
   The condition code is set by this instruction in all cases:
 
                                Condition Code             Meaning                   Test With
 
                    0            Result = 0       BZ, BE
                    1            Result < 0       BL, BM
                    2            Result > 0       BH, BP
 
   Consider the following instruction.
 
                            SRDA  R8,3
 
This instruction represents a right algebraic shift of registers 8 and 9 using a shift factor of 3.  The shift factor has been coded
directly.  As a result, 3 bits, 000, are shifted out of the register on the right.  Vacated bit positions on the left are replace by 1’s (the

http://csc.columbusstate.edu/woolbright/SRDA.HTM[9/21/2011 4:23:10 PM]


shift right algebraic
Contents
sign bit is negative).  This is illustrated in the diagram below.  The condition code is set to 1, indicating that the resulting binary
integer is negative.
 
 

   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SRDA’s


 
               R4 = B’11111111111111111111111111110000’
               R5 = B’11110000111100001111000011110000’
               R6 = B’00000000000000000000000000001111’
               R7 = B’00000000000000000000000000000000’
        
  SRDA  R4,1     R4 = B’11111111111111111111111111111000’  Cond.Code = 1
                 R5 = B’01111000011110000111100001111000’
  SRDA  R4,2     R4 = B’11111111111111111111111111111100’  Cond.Code = 1
                 R5 = B’00111100001111000011110000111100’
  SRDA  R4,32    R4 = B’11111111111111111111111111111111’  Cond.Code = 1
                 R5 = B’11111111111111111111111111110000’ 
  SRDA  R6,32    R6 = B’00000000000000000000000000000000’  Cond.Code = 2
                 R7 = B’00000000000000000000000000001111’ 

1)  SRDA is a helpful instruction to use when dividing binary numbers.  Remember that the divide instruction requires that the
even-odd pair or registers be initialized with the dividend.  In other words, the even-odd pair contains a 64-bit 2’s complement
integer.  One way to initialize the pair is to load the even register with a fullword that represents the dividend, and then shift it
using SRDA to the odd register.  This operation propagates the sign bit throughout the even register.  For example, to divide the
fullword X by the fullword Y, the following code could be used.
 
              L      R4,X     PUT DIVIDEND IN THE EVEN REGISTER
              SRDA   R4,32    SHIFT DIVIDEND TO THE ODD REGISTER
              D      R4,Y     READY TO DIVIDE
 

http://csc.columbusstate.edu/woolbright/SRDA.HTM[9/21/2011 4:23:10 PM]


shift right double logical
Contents

 
   Operand 1 specifies the even register of an even-odd consecutive pair of general purpose registers.  For instance, R4 would
represent registers 4 and 5, while R8 would represent registers 8 and 9.  SRDL is used to shift the 64 bits in the even-odd pair as
if they comprised a single register.  The shift is to the right.  The number of bits that are shifted is indicated by Operand 2.  The
second operand address is not used to address data; instead, the base/displacement address is computed and the rightmost 6 bits
are treated as a binary integer which represents the number of bits to be shifted.  We will call this value the “shift factor”.  This
leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SRDL  R8,8
 
In the above shift, the second operand, 8, is treated as a base/displacement address where 8 is the displacement and the base
register is omitted.  The effective address is 8. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 8, and so the bits in registers 8 and 9 are shifted to the right by 8 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SRDL R6,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting logically, bits shifted out on the right are lost, while 0’s replace bits on the left.
 
   Consider the following instruction.
 
                            SRDL  R8,6
 
This instruction represents a right shift of registers 8 and 9 using a shift factor of 6.  The shift factor has been coded directly.  As a
result, 6 bits, 110000, are shifted out of the register on the right.  Vacated bit positions on the left are replaced by 0’s.  This is
illustrated in the diagram
below.
 

http://csc.columbusstate.edu/woolbright/SRDL.HTM[9/21/2011 4:23:11 PM]


shift right double logical
Contents

   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SRDL’s


 
               R4 = B’11111111111111111111111111111111’
               R5 = B’11110000000000000000000000000000’
        
          SRDL  R4,1     R4 = B’01111111111111111111111111111111’
                         R5 = B’11111000000000000000000000000000’
          SRDL  R4,2     R4 = B’00111111111111111111111111111111’
                         R5 = B’11111100000000000000000000000000’
          SRDL  R4,3     R4 = B’00011111111111111111111111111111’
                         R5 = B’11111110000000000000000000000000’
          SRDL  R4,31    R4 = B’00000000000000000000000000000001’
                         R5 = B’11111111111111111111111111111111’
          SRDL  R4,32    R4 = B’00000000000000000000000000000000’
                         R5 = B’11111111111111111111111111111111’
 
          L    R9,=F’3’
          SRDL R4,0(R9) R4 = B’00011111111111111111111111111111’
                        R5 = B’11111110000000000000000000000000’
 
          L    R3,=F’5’
          SRL  R4,0(R3) R4 = B’00000111111111111111111111111111’
                        R5 = B’11111111100000000000000000000000’

http://csc.columbusstate.edu/woolbright/SRDL.HTM[9/21/2011 4:23:11 PM]


shift right logical
Contents

 
   SRL is used to shift the 32 bits in the register specified by Operand 1 to the right.  The number of bits that are shifted is
indicated by Operand 2.  The second operand address is not used to address data; instead, the base/displacement address is
computed and the rightmost 6 bits are treated as a binary integer which represents the number of bits to be shifted.  We will call
this value the “shift factor”.  This leads to two distinct ways of coding the shift factor:
 
   1)   Directly -  The shift factor is coded as a displacement.  Consider the example below.
 
                            SRL  R9,8
 
In the above shift, the second operand, 8, is treated as a base/displacement address where 8 is the displacement and the base
register is omitted.  The effective address is 8. (See Explicit Addressing.)  When represented as an address the rightmost 6 bits
still represent the number 8, and so the bits in register 9 are shifted to the right by 8 bits.
 
   2)  Indirectly -  The shift factor is placed in a register and the register is mentioned as the base register in the
base/displacement address.
                           
                      L    R5,FACTOR    PUT SHIFT FACTOR IN REG
                      SRL  R9,0(R5)     NOW SHIFT INDIRECTLY
                      ...
               FACTOR DC   F’8’         SHIFT FACTOR IS 8 BITS
 
In this case, the effective address is computed by adding the contents of base register 5 (which is 8), with the displacement of 0. 
The effective address is again 8, and the rightmost 6 bits of this address indicate that the shift factor is 8.
 
   Each method has its uses.  The direct method is useful in situations where the number of bits you want to shift is fixed.  Coding
directly allows you to look at the instruction to determine the shift factor.  On the other hand, the indirect method allows the shift
factor to be determined while the program is executing.  If the shift factor cannot be determined until the program is running, the
indirect method must be used.
 
   When shifting logically, bits shifted out on the right are lost, while 0’s replace bits on the left.
 
   Consider the following instruction.
 
                            SRL  R8,6
 
This instruction represents a right shift of register 8 using a shift factor of 6.  The shift factor has been coded directly.  As a result,
6 bits, 110000, are shifted out of the register on the right.  Vacated bit positions on the left are replace by 0’s.  This is illustrated in
the diagram below.

http://csc.columbusstate.edu/woolbright/SRL.HTM[9/21/2011 4:23:12 PM]


shift right logical
Contents

 
   This instruction has an RS format but the 4 low-order bits of the second byte are unused.
 

             Some Unrelated SRL’s


 
               R5 = B’11111111111111111111111111111111’
               R6 = B’11110000111100001111000011110000’
        
          SRL  R5,1     R5 = B’01111111111111111111111111111111’
          SRL  R5,2     R5 = B’00111111111111111111111111111111’
          SRL  R5,3     R5 = B’00011111111111111111111111111111’
          SRL  R5,31    R5 = B’00000000000000000000000000000001’
          SRL  R5,32    R5 = B’00000000000000000000000000000000’
          SRL  R6,4     R6 = B’00001111000011110000111100001111’
 
          L    R9,=F’3’
          SRL  R5,0(R9) R5 = B’00011111111111111111111111111111’
 
          L    R3,=F’5’
          SRL  R5,0(R3) R5 = B’00000111111111111111111111111111’

http://csc.columbusstate.edu/woolbright/SRL.HTM[9/21/2011 4:23:12 PM]


SHIFT AND ROUND PACKED
Contents

 
 
   SRP is a SS 1 instruction designed to shift the digits in a packed decimal field either left or right while leaving the sign of the field
fixed in its position.  For right shifts, the last digit that is shifted off can be rounded using a rounding factor.  As digits are shifted off
during a left shift, 0’s are shifted in on the right.  On the other hand, as digits are shifted off during a right shift, 0’s are shifted in
on the left.
 
   Consider the explicit format for this instruction.

                          
As we can see from the diagram,  operand 1 specifies the field to be shifted and its length, while the third operand is a rounding
factor.  This factor is added to the last digit which is shifted off during right shifts.  Typically, you would code the third operand as 5
in order to round up on a digit of 5 or greater.  Coding 0 as the third operand indicates no rounding.  A rounding factor must
always be coded, even when shifting left.
 
   The second operand above receives special treatment.  The notation D2(B2) is converted to an effective address and the last 6
bits of this address is treated as a two’s complement number that indicates the number of digits to be shifted and in which
direction.  A positive number indicates a left shift and a negative number indicates a right shift.  Because of the explicit notation,
there are two standard ways to code the second operand.
 
1)  Displacement Only - 
                    SRP    XPK,3,0
 
In this case the shift factor, 3, is converted to 6-bit binary (B’000011’) and the result is interpreted as 6-bit 2’s complement.  In this
format B’000011’ is considered to be positive 3 - a left shift by 3.  
 
On the other hand consider the following example,
   
                    SRP    XPK,62,5
 
     The 62 is converted to its binary form (B’111110’) and interpreted as a 6-bit 2’s complement integer.  We see that B’111110’ = -
2 in base 10.  This means the previous shift is a 2-digit right shift.
 
   There is a simple way to deal with the shift factor on right shifts.  Simply express the shift factor as 64 - n, where n is the
number of digits you wish to shift to the right.  For example, the previous example could be expressed as   SRP    XPK,64-2,5 . 

http://csc.columbusstate.edu/woolbright/SRP.HTM[9/21/2011 4:23:13 PM]


SHIFT AND ROUND PACKED
Contents
The 64 - n expression produces the correct decimal number which will be interpreted as a negative 2’s complement integer.
 
2)  Base Register Only -
                    SRP    XPK,0(R8),5
 
     In this format the base register (R8) is initialized with a number representing the shift factor.  Because 0 was coded for the
displacement, the effective address will be computed to be the contents of the specified register.  The number of digits to be
shifted and the direction is solely determined by the contents of the register at the time the instruction is executed.  This allows us
to dynamically change the shift factor.  Consider the code below.
 
                    LA    R6,10        SHIFT FACTOR = 10 DIGITS LEFT
                    SRP   XPK,0(R6),5  DYNAMIC SHIFT
 
  The number 10 (indicating a 10-digit left shift) is loaded into R6.  The effective address will be 10.
  
   Here are two example SRP’s that indicate what happens at the byte level.

 
 

          Some unrelated SRP’s:


 
   APK      DC    PL4’126’          = X’0000126C’
   BPK      DC    PL4’1122334’      = X’1122334C’
                  RESULTS:
            SRP   APK,3,5       APK = X’0126000C’  LEFT SHIFT 3
            SRP   APK,3,0       APK = X’0126000C’  ROUNDING UNIMPORTANT
            SRP   APK,64-2,5    APK = X’0000001C’  RIGHT SHIFT
            SRP   APK,64-1,5    APK = X’0000013C’  ROUND UP >= 5
            SRP   BPK,1,5       OVERFLOW OCCURS ON LOSING SIG. DIGIT
            SRP   APK,-2,5      ASSEMBLY ERROR - NEGATIVE DISPLACEMENTS
                                ARE NOT ALLOWED

 
 
1.   Keep in mind that you cannot left shift off a significant digit.
 
2.  Be sure to use the 64-n notation when coding right shifts.  It is easy to read, and provides excellent documentation.

http://csc.columbusstate.edu/woolbright/SRP.HTM[9/21/2011 4:23:13 PM]


ST
Contents

 
 
   ST is used to copy the fullword stored in the register specified by operand 1 into the fullword memory location specified by
operand 2.  Consider the following example,    
 
                            ST    R9,AFIELD
 

          
In this case, the contents of register 9 are copied to the fullword in memory denoted by AFIELD.  This operation destroys the
previous contents of AFIELD but leaves R9 unchanged.
 
   Since ST is an RX instruction, an index register may be coded as part of operand 2.  Notice that in the previous example, no
index register was specified.  When the index register is omitted, the assembler chooses R0, which does not contribute to the
address. The following example illustrates this idea.
 
                           ST     R9,AFIELD(R5)
 
   The assembler converts AFIELD to a base register and displacement, while R5  is the index register.  For instance, the
expression AFIELD(R5) might (we can not determine the base register) be equivalent to the explicit address   0( R5,R3 )  - 
displacement = 0, index register = R5, base register = R3 (see Explicit Addressing).  The effective address is computed by
adding the base register contents to the index register contents plus the displacement.  If the index register contains an “8”, then
AFIELD(R5) refers to the fullword that begins at an 8 byte displacement from the beginning byte of AFIELD.  The following
examples illustrate several explicit addresses that include an index register.
 

http://csc.columbusstate.edu/woolbright/ST.HTM[9/21/2011 4:23:14 PM]


ST
Contents

 
 
   In the first explicit address, 4( R4, R3), the effective address is computed by adding the contents of base register 5, the contents
of index register 3, and the displacement ( 1000 + 4 + 4 = 1008 ).  The second address 0( R5, R3) is computed as 1000 + 8 + 0 =
1008, and the third address, 4( R5, R3 ) is computed to be 1000 + 8 + 4 = 100C (hexadecimal).
 
   If an index register is not explicitly coded, as in the instruction “ST     R9,AFIELD”, the assembler chooses R0 as the index
register, which does not contribute to the effective address.
 

          Some Unrelated ST’s


 
              R7 =  X’00001000’
              R8 =  X’00000004’
              R9 =  X’00000008’
             
    AFIELD   DC  F’20’      AFIELD = X’00000016’
    BFIELD   DC  F’-1’      BFIELD = X’FFFFFFFF’
    CFIELD   DC  F’0’       CFIELD = X’00000000’
   
             ST   R7,AFIELD     AFIELD = X’00001000’
             ST   R8,AFIELD     AFIELD = X’00000004’
             ST   R8,BFIELD     BFIELD = X’00000004’
             ST   R7,AFIELD(R8)  CHANGES BFIELD TO X’00001000’
             ST   R7,AFIELD(R9)  CHANGES CFIELD TO X’00001000’

1)  Operand 2 should denote a fullword in memory.  It is possible to store the contents of a register into 4 bytes of memory that are
not aligned on a fullword, but the assembler will warn you that operand 2 is not properly aligned.  If the field involved cannot be
aligned conveniently, consider using STCM to copy the contents of a register into memory.

http://csc.columbusstate.edu/woolbright/ST.HTM[9/21/2011 4:23:14 PM]


stc
Contents

 
 
   STC is used to copy the rightmost byte of a register into main storage.  The register is represented by operand 1, and the main
storage area is designated by operand 2.  Since STC is an RX instruction, the storage area can be designated by using an index
register.

 
 
   The STC instruction above takes the rightmost byte of register 8 and copies it into the first byte of FIELDA, a field in main
storage.  One advantage to STC is the ability to use an index register to move a single byte from a register to memory.  STC and
IC are the only byte-oriented RX instructions.  In the following example we assume that register 5 contains x’000000C1’ and that
register 7 contains x’00000003’. 
 
                         STC    R5,FIELDA(R7)   
 
The instruction above would store the character “A” (x’C1’) into the fourth byte of FIELDA.

 
    
    For the following examples, assume that R8 contains x’11223344’ and that R4 contains x’00000002’
 
          FIELDA   DC    X’AABBCCDD’

http://csc.columbusstate.edu/woolbright/STC.HTM[9/21/2011 4:23:15 PM]


stc
Contents
          FIELDB   DC    C’ABCD’
                                       Result:
                   STC   R8,FIELDA     FIELDA = x’44BBCCDD’
                   STC   R8,FIELDA(R4) FIELDA = x’AABB44DD’
                   STC   R8,FIELDB     FIELDB = x’44C2C3C4’
                   STC   R8,FIELDB(R4) FIELDB = x’C1C244C4’

1.  Remember that STC is a byte oriented instruction that only copies the rightmost byte of a register.  The companion to STC is IC
(Insert Character).

http://csc.columbusstate.edu/woolbright/STC.HTM[9/21/2011 4:23:15 PM]


Store halfword
Contents

 
 
   The STH instruction has two operands: the first operand is a general purpose register, and the second operand is a halfword
storage area in memory.  The effect of the instruction is to copy the contents of bits 16-31 of the Operand 1 register (the rightmost
two bytes)  into the halfword specified by Operand 2. The condition code is unaffected by this instruction.  Consider the following
example.    
 
                            STH    R9,AFIELD       
 

 
   The rightmost two bytes of register 9 are copied to the halfword AFIELD, destroying the previous contents.  The register value is
unchanged by this operation.
 
   Since STH is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 

          Some Unrelated Store Halfwords


 
              R4 =  X’00000000’
              R5 =  X’12345678’
              R6 =  X’00000004’    
  
    AFIELD   DC  H’4’       AFIELD = X’0004’
    BFIELD   DC  H’25’      BFIELD = X’0019’
    CFIELD   DC  H’0’       CFIELD = X’0000’
   
             STH   R4,AFIELD     AFIELD = X’0000’
             STH   R4,BFIELD     BFIELD = X’0000’
             STH   R4,CFIELD     CFIELD = X’0000’
             STH   R5,AFIELD     AFIELD = X’5678’
             STH   R6,BFIELD     BFIELD = X’0004’ 
 
           
 
             CONSIDER THE NEXT TWO CONSECUTIVELY EXECUTED INSTRUCTIONS
             LH   R8,AFIELD     R8 = X’00000004’
             STH  R5,AFIELD(R8) BFIELD = X’5678’

http://csc.columbusstate.edu/woolbright/STH.HTM[9/21/2011 4:23:16 PM]


stm
Contents

 
   STM is used to copy a “consecutive” collection of registers into consecutive fullwords in main storage.  The collection of registers
which is copied is specified by coding the beginning and ending registers as the first two operands.  For instance,
 
                      STM  R5,R8,XWORDS
 
would be used to copy registers 5, 6, 7, and 8.  If the second operand specifies a lower register than the first operand, then a
“wrap-around” occurs.  For instance,
 
                      STM  R14,R12,12(R13)
 
would be used to copy registers 14, 15, 0, 1, ..., 12 - every register except 13.
 
   The registers are stored starting in the fullword address specified in the third operand.  In the first example above, register 5
would be stored at XWORDS, register 6 at XWORDS+4, register 7 at XWORDS+8, and  register 8 at XWORDS+12.  In the second
example, register 14 is stored at an explicit address -  a 12 byte displacement off register 13.  The other registers are consecutively
stored.
 
   Here is an example.
 
                     STM   R7,R9,REGWORDS
 

   In the example above, the consecutive range of registers ( 7, 8, and 9 ) are stored in consecutive fullwords in memory starting in
the fullword specified as REGWORDS.
 

           Some Unrelated STM’s


 
      XWORD    DS    F

http://csc.columbusstate.edu/woolbright/STM.HTM[9/21/2011 4:23:17 PM]


stm
Contents
               ...
               STM   R5,R6,XWORD     XWORD   = CONTENTS(R5)
                                     XWORD+4 = CONTENTS(R6)
               STM   R15,R1,XWORD    XWORD   = CONTENTS(R15)
                                     XWORD+4 = CONTENTS(R0)
                                     XWORD+8 = CONTENTS(R1
               STM   R14,R12,12(R13) THIS STORES ALL REGISTERS EXCEPT 13
                                     12 BYTES OFF REGISTER 13.  SEE
                                     THE TOPIC ON PROGRAM LINKAGE  

1)  This statement is helpful for creating subroutines.  Branch to a subroutine and immediately save the registers with STM.  This
allows your subroutine to freely use the registers.  Before exiting your subroutine, restore the registers with LM.  Create a register
“save area” for each subroutine.
 
                 BAS    R6,SUBRTN    CALL THE SUBROUTINE
                 ...
        SUBRTN   EQU    *
                 STM    R14,R12,SUBSAVE    SAVE THE REGISTERS
                 ... (SUBROUTINE CODE)
                 LM     R14,R12,SUBSAVE    RESTORE THE REGISTERS
                 BR     R6           BRANCH BACK TO CALLER 
        SUBSAVE  DS     15F          FIFTEEN FULLWORDS FOR THE REGISTERS
 
2)  Read about the role that STM plays in implementing the “linkage conventions” in Program Linkage .  

http://csc.columbusstate.edu/woolbright/STM.HTM[9/21/2011 4:23:17 PM]


Subtract Halfword
Contents

 
 
   The Subtract Halfword instruction performs 2’s complement binary subtraction.  Operand 1 is a register containing a fullword
integer.  Operand 2 specifies a halfword in memory.  The halfword in memory is sign extended (internally) and subtracted from the
fullword in the register.  The result remains in the register.  The halfword in memory is not changed.  Consider the following
example,    
 
                            SH    R9,AFIELD       
 

   The contents of the halfword “AFIELD”, x’007F’ = 127, are subtracted from register 9 which contains x’000003FA’ = 1018.  The
difference, 891 = x’0000037B’, destroys the previous value in R9.  The halfword in memory is unchanged by this operation.
 
   Since SH is an RX instruction, an index register may be coded as part of operand 2 (see Explicit Addressing).
 

          Some Unrelated Subtract Halfwords


 
              R4 =  X’FFFFFFF0’  -16 IN 2’S COMPLEMENT
              R5 =  X’00000025’  +37 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
 
              DOG   DC   H’4’,H’9’,H’-25’,H’3’   CONSECUTIVE HALFWORDS
 
              SH    R4,=H’20’    R4 = X’FFFFFF1C’ = -36
              SH    R5,=H’20’    R5 = X’00000011’ = +17
              SH    R6,=H’4’     R6 = X’00000000’ =  0
              SH    R4,=H’-9’    R4 = X’FFFFFFF9’ = -7
              SH    R5,DOG       R5 = X’00000021’ = +33
              SH    R5,DOG(R6)   R6 = X’0000003E’ = +28 INDEXING ALLOWED

   A common error is to code a SH when the second operand is not a halfword.  For example:
 
         AMOUNT    DC   F’20’        AMOUNT = X’00000014’
                   ...
                   SH   R5,AMOUNT
 
The assembler will not complain about your code, but the halfword instruction will only access the first two bytes of the AMOUNT
field (x’0000’).

http://csc.columbusstate.edu/woolbright/SUBHALF.HTM[9/21/2011 4:23:18 PM]


subpack
Contents

 
   SP is a SS 2 instruction which is used to subtract packed decimal fields.  Operand 1 is a field in storage which should contain a
packed decimal number.  The resulting sum develops in this field.  The contents of Operand 2, another packed decimal field in
storage, is subtracted from the contents of Operand 1 to produce the result which is stored in Operand 1.   The operands are
limited to a maximum length of 16 bytes and may have different sizes since this is a SS 2   instruction.
 
  A decimal overflow (condition code = 3) will occur if the generated result loses a significant digit when it is placed in the target
field.  A decimal overflow may or may not cause a program interruption (abend).  This depends on the setting of a bit in the PSW
(See SPM).  Otherwise, the condition code is set to indicate whether the result was zero (condition code = 0), negative (condition
code = 1), or positive (condition code = 2).  You can test these conditions with BZ or BNZ, BM or BNM, and BP or BNP.
 
   Consider the following SP example.
 
                       SP      APK,BPK
                       BM      ANEGATIV
 
Assume the variables are initially in  the following states,
 
              APK      DC      PL4’34’  = X’0000034C’
              BPK      DC      PL3’22’  = X’00022C’
 
After the SP instruction has executed,  the variables have the following values.
     
              APK  = X’0000012C’
              BPK  = X’00022C’
 
The contents of BPK was subtracted from APK and the result stored in APK.  BPK was unaffected by the subtract operation.  The
branch is not taken since the condition code is positive.
 
   On the other hand, consider the following example,
 
                       SP      APK,BPK
                                                ...
              APK      DC      PL2’999’  = X’999C’
              BPK      DC      PL2’-5’    = X’005D’
 
After the SP instruction has executed,  the variables have the following values.
     
              APK  = X’004C’
              BPK  = X’005D’
 
Notice that an overflow occurred in APK with the loss of a significant digit.  APK was too small to hold the difference that
developed as a result of the SP.
 

          Some unrelated SP’s:


 
 A        DC      P’12345’      = X’12345C’
 B        DC      P’-32’        = X’032D’    
 C        DC      Z’11’         = X’F1C1’
          ...

http://csc.columbusstate.edu/woolbright/SUBPACK.HTM[9/21/2011 4:23:19 PM]


subpack
Contents
                           Results:
          SP    A,=P’20’   A = X’12325C’   C.C. = HIGH
          SP    B,=P’20’   B = X’052D’     C.C. = LOW 
          SP    B,=P’-40’  B = X’0008C’    C.C. = HIGH  
          SP    A,=P’1’    A = X’12344C’   C.C. = HIGH
          SP    A,B        A = X’12377C’   C.C. = HIGH
          SP    B,B        B = X’000C’     A FIELD CAN BE SUBTRACTED
                                           FROM ITSELF
                                           C.C. = EQUAL
          SP    B,A        B = X’377D’    AN OVERFLOW OCCURS
          SP    A,C                       DATA EXCEPTION - C NOT PACKED
 
 

 
1.  You must be familiar with your data.  The best way to prevent overflows is to plan the size of your fields based on the data at
hand.  There is a rule of thumb that you can follow for subtractions:  If you are subtracting two packed fields with m and n bytes,
then the difference  might be as large as max(m, n) + 1 bytes.  You may need to construct a work area to handle the maximum
values.  For instance,
 
                  FIELDA   DS    PL3
                  FIELDB   DS    PL5
                  WORK     DS    PL6
 
In planning to subtract FIELDB from FIELDA,  we construct a work field called “WORK”.  The following code completes the task.
 
                        ZAP    WORK,FIELDA
                        SP     WORK,FIELDB
 

http://csc.columbusstate.edu/woolbright/SUBPACK.HTM[9/21/2011 4:23:19 PM]


subtract register
Contents

                                                             
 
   The Subtract Register instruction performs 2’s complement binary subtraction.  Operand 1 is a register containing a fullword
integer.  Operand 2 specifies a register as well.  The fullword in Operand 2 is subtracted from the fullword in Operand 1,  and the
difference replaces the contents of Operand 1.  Operand 2 in unchanged by this operation except when Operand 1 and 2 refer to
the same register.  Consider the following example,    
 
                            SR    R9,R8

               
 
 
   The contents of the fullword in register 8, x’00000479’, are subtracted from the contents of register 9 which contains x’000003FA’
.  The difference is x’00000181’  and replaces the previous value in R9.  The contents of register 8 are unchanged by this
operation.
 
   The condition code is set by this instruction to zero if the result is zero, minus if the result is negative, and plus if the result is
positive.
 

            Some Unrelated Subtract Registers


 
              R4 =  X’FFFFFFFE’   -2 IN 2’S COMPLEMENT
              R5 =  X’00000028’  +40 IN 2’S COMPLEMENT
              R6 =  X’00000004’   +4 IN 2’S COMPLEMENT
  
              SR    R4,R4    R4 = X’00000000’ = 0
              SR    R5,R4    R4 = X’0000002A’ = +42
              SR    R5,R6    R5 = X’00000018’ = +24
              SR    R6,R5    R6 = X’FFFFFFE8’ = -24

http://csc.columbusstate.edu/woolbright/SUBREG.HTM[9/21/2011 4:23:20 PM]


test under mask
Contents

                                                  
  
 
   Test Under Mask is used to examine the bits of a single byte in memory and set the condition code based on the contents of the
selected bytes.  Operand 1 is the address of the byte in memory that is to be examined.  Operand 2 is an immediate constant
which is treated as an 8-bit binary mask (pattern).  The bits in the mask correspond one for one with the bits in the Operand 1
byte.  A mask bit of 1 indicates that we are interested in testing the corresponding bit in memory and we will call this bit a
“selected” bit.  A mask bit of 0 indicates that we are not interested in testing the corresponding bit in memory.  The condition code
is set based on the contents of the selected bits. 
 
   This instruction sets the condition code as follows:
 
   Condition Code               Meaning                                    Test With
 
            0              All selected bits are set to 0,                      BZ or BNZ.  (Zeros, Not Zeros)
                           or all mask bits were 0
            1             Selected bits mixed (0’s and 1’s)                BM or BNM ( Mixed, Not Mixed)
)
            3             Selected bits were all 1’s                            BO    BNO  (Ones, Not Ones)            
 
   Consider the following example.
 
                         TM   AFIELD,B’11110000’
                         BO   ALLONES
                         BM   MIXED
                         ...
                 AFIELD  DC   C’A’        AFIELD = B’11000001’
 
The immediate constant in the TM instruction is coded as B’11110000’, indicating that we are interested in testing the first four bits
in AFIELD, and that we are not interested in the last four bits.  Since AFIELD contains a character “A” which is equivalent to a
binary 11000001, the condition code is set to 1 indicating that some of the bits we selected are 1’s and some are 0’s.  As a result,
a branch will occur to MIXED when we execute the BO instruction.
 
   Since the TM instruction works at the bit level, it makes sense to code the immediate constant in a binary format, although any
format may be used.  For example, the following instruction is equivalent to the TM in the example above.
 
                      TM   AFIELD,X’F0’
 
 
 
 
 
 

        Some Unrelated TM’s


 
              BYTE1  DC   X’00’
              BYTE2  DC   X’FF’
              BYTE3  DC   X’C3’
 
       TM    BYTE1,B’11000000’   Condition Code = 0 (all zeros)
       TM    BYTE2,B’11000000’   Condition Code = 1 (mixed)

http://csc.columbusstate.edu/woolbright/TM.HTM[9/21/2011 4:23:21 PM]


test under mask
Contents
       TM    BYTE3,B’11000000’   Condition Code = 3 (all ones)
 

1)  Make your code easier to read by representing the immediate constant in a binary form.

http://csc.columbusstate.edu/woolbright/TM.HTM[9/21/2011 4:23:21 PM]


tr
Contents

 
     TR is used to translate one string of characters to another string of characters based on a translate table which defines the
substitutions which should occur.  For instance, TR could be used to convert a string of characters from lower case to upper case,
or from ASCII to EBCDIC.
 
    Operand 1 designates a string contain in memory which is to be translated.  Operand 2 designates the translate table.  This
table is also called a “table of functions”.  TR translates one byte at a time, starting with the leftmost byte of Operand 1, proceding
from left to right. Each byte that is translated is used as a displacement into the table.  The “function byte” that is found in the table
is substituted for the byte in Operand 1.  Since a byte can contain any value from X’00’ to X’FF’, the table of functions is usually
256 bytes long to accommodate the range of addresses from table + X’00’ to table + X’FF’. 
 
   Let us consider how a particular byte is translated using a table of functions called “TABLE”.  For example, how would a byte
containing X’A2’ be translated?  Since X’A2’ = 162 in base 10, X’A2’ would be replaced by the byte at address “TABLE+162”.  In
other words, the byte we are translating acts as a displacement into the table, and is replace by the table byte in that position.
 
   Consider the following example.  To keep things simple, we begin with a small ( 5 bytes ) table and assume that the bytes in the
string which is being translated generate displacements that  stay inside the table.  ( For safety, most TR tables are 256 bytes in
length. ) We assume the following definitions.
 
                   STRING    DC   X’030201’
                   TABLE     DC   X’FF01AABB00’
 
We issue the following command.
 
                             TR   STRING,TABLE
 
   The execution of this instruction is graphically illustrated on the next page.   Let us consider a byte by byte description of the
execution of TR.  The first byte of STRING, X’03’, is used as a displacement into TABLE.  The byte at address         TABLE+3,
which is X’BB’, replaces the first byte in STRING.  This means the string temporarily looks like X’BB0200’.  Next, the second byte
of STRING, X’02’, is used as a displacement into the table.  As a result the byte at TABLE+2, which is X’AA’, replaces X’02’ in
STRING.  Finally, the third byte in STRING, X’01’, is used as a displacement into the table and the byte at TABLE+1, X’01’,
replaces X’01’ in STRING.  After the TR has executed, STRING contains X’BBAA01’.

http://csc.columbusstate.edu/woolbright/TR.HTM[9/21/2011 4:23:22 PM]


tr
Contents

 
   To be safe when using TR you should always code a translate table that is 256 bytes long so that you can handle any possible
displacement that might be used in the translation.  The only exception to this rule occurs when you are sure that the bytes you are
translating fall within a specified range. 
 
 How could you define a translate table that translates every character to itself?  Since each character would be used as a
displacement to itself, a translate table of this type would look like X’000102030405060708090A0B0C0D0E0F10...’.  There is an
easy way to construct such a table:                  TABLE   DC   256AL1(*-TABLE)
This technique works by defining 256 byte address constants of length 1.  When defining the first byte in the table the asterisk
refers to the same address as TABLE, and so *-TABLE is 0.  After defining the first byte the location counter advances and *-
TABLE is 1 when defining the second byte.  Continuing in this fashion, the expression “*-TABLE” takes on all the values from 0 to
256. As a result, we create a table that translates every character to itself.  This is important because in many applications, most of
the characters we encounter are left unchanged by TR.
 
   For example, suppose we want to translate lower case letters to upper case.  To do this we use the following table definition.
 
                 TABLE     DC    256AL1(*-TABLE)
                           ORG   TABLE+C’a’
                           DC    C’ABCDEFGHI’
                           ORG   TABLE+C’j’
                           DC    C’JKLMNOPQR’
                           ORG   TABLE+C’s’
                           DC    C’STUVWXYZ’
                           ORG
 
Notice that most bytes translate to themselves.  An originate directive is used to position to the table position that contains a lower
case “a”.  This is followed by a DC that defines the upper case letters A - I.  This technique is repeated for “j” and “s”.  Since the
lower case letters occur in 3 blocks ( A - I, J - R, and S - Z ) the DC’s above provide for the conversion from lower to upper case.

http://csc.columbusstate.edu/woolbright/TR.HTM[9/21/2011 4:23:22 PM]


tr
Contents
  
 

          Some Unrelated TR’s:


 
      TABLE     DC    X’0302010300’    VERY SMALL TRANSLATE TABLE
   A         DC    X’040404’
   B         DC    X’000003020201’    
   C         DC    X’00000000’
   D         DC    X’01010101’
   E         DC    X’020202’
   F         DC    X’010203’
                   ...             Result:
             TR    A,TABLE        A = X’000000’
             TR    B,TABLE        B = X’03030301010102’
             TR    C,TABLE        C = X’03030303’
             TR    D,TABLE        D = X’02020202’
             TR    E,TABLE        E = X’010101’
             TR    F,TABLE        F = X’020103’

 
1.  Start with a table that translates each byte to itself ( TABLE   DC  256AL1(*-TABLE) ).  Use “ORG” to position yourself to an
appropriate character ( ORG   TABLE+C’X’ positions you at ‘X’.)  Redefine the area with a ‘DC’.
 
2.  Avoid translation errors by defining all translate tables with 256 bytes.
 
 

http://csc.columbusstate.edu/woolbright/TR.HTM[9/21/2011 4:23:22 PM]


trt
Contents

 
     TRT is used to scan a string of characters, searching for the occurrence of any the characters which are specified in a translate
table.  The translate table is usually 256 bytes in length - one  for each possible EBCDIC character that might be encountered
during the search.  Unlike TR which provides automatic translation of character strings, TRT sets up the conditions for a translate
to occur, but leaves the programmer with the task of making the translation.  In many cases, TRT is used for scanning strings with
no intention of making a translation.
 
    Operand 1 designates a string contained in memory which is to be scanned and possibly translated.  Operand 2 designates the
translate table.  This table is also called a “table of    functions”.  TRT scans one byte at a time, starting with the leftmost byte of
Operand 1, proceding from left to right. Each “string byte” that is scanned is used as a displacement into the table.  The byte in the
translate table at the given offset is called the “function byte”.  If the function byte is X’00’, the scanning process continues with the
next byte in Operand 1.  In other words, a X’00’ in a function byte indicates that we are not interested in finding the string byte that
was used as a displacement.  On the other hand, if the function byte is not X’00’, then TRT modifies register 1 to contain the
address of the current string byte and also modifies register 2 to contain the corresponding function byte in bits 24 - 31 (the
rightmost byte of the register).  The TRT operation is terminated when a nonzero function byte is encountered.  At this point the
programmer is free to make the translation using registers 1 and 2.
 
   Since a string byte can contain any value from X’00’ to X’FF’, the table of functions is usually 256 bytes long to accommodate the
range of addresses from table + X’00’ to table + X’FF’.  Let us consider how a particular string byte is processed using a table of
functions called “TABLE”.  For example, how would a byte containing X’A2’ be processed?  Since X’A2’ = 162 in base 10, the
function byte at address “TABLE+162” would be examined.  If the function byte were X’00’, execution would continue with the next
string byte (moving from left to right within the string).  If the function byte contained something different from X’00’, then register 1
would contain the address of the current string byte and register 2 would contain the corresponding function byte.
 
   TRT also sets the condition code to indicate the results of the scanning operation as follows:
 
    Condition Code        Indications
 
              0  ( Zero )          All function bytes encountered were X’00’.
              1  ( Minus )        A  nonzero function byte was found before the end of operand 1
              2  ( Positive )     A nonzero function byte was found at the end of the operand 1
 
The condition code can be tested using BZ, BNZ, BM, BNM, BP, or BNP.
 
   Consider the following example.  To keep things simple, we begin with a small ( 5 bytes ) table and assume that the bytes in the
string which is being scanned generate displacements that stay inside the table.  We assume the following definitions.
 
                   STRING    DC   X’04010303’
                   TABLE     DC   X’0000FFFF00’
 
Notice that the table indicates that we are interested in finding a string byte that contains X’02’ or X’03’.  Those bytes contain
X’FF’.  We are not interested in scanning for X’00’, X’01’, or X’04’ since those table bytes contain X’00’.
 
   We issue the following command.
 
                             TR   STRING,TABLE
 

http://csc.columbusstate.edu/woolbright/TRT.HTM[9/21/2011 4:23:23 PM]


trt
Contents

 
 
   The previous diagram indicates the result of the TRT.  First the string byte X’04’ is used as a displacement into the table of
functions.  The function byte in this position is X’00’.  As a result, execution continues with the next string byte.  Using X’01’ as a
displacement we find the function byte X’00’.  Execution continues with the next string byte.  Finally, X’03’ is used as a
displacement into the table of functions and we find a nonzero function byte X’FF’.  Execution of TRT terminates at this point with
the condition code set to “Minus” to indicate that a nonzero function byte was found before the end of the string.
 
   When defining a TRT table we are usually interested in finding only a few selected characters.  This means we can begin
defining a TRT table by starting with a table of all zeros and use a collection of ORG’s to redefine the pertinent characters.  The
following example shows how to
code a table to scan for a dollar sign or a question mark.
 
 
                      TABLE     DC    256AL1(0)
                      ORG   TABLE+C’$’   Scan for a dollar sign
                      DC    X’FF’
                      ORG   TABLE+C’?’   Scan for a question mark
                      DC    X’FF’
                      ORG
 
 

          Some Unrelated TRT’s:


 
      TABLE    DC    256AL1(0)
             ORG      TABLE+C’*’
             DC       C’X’        ANY NONZERO VALUE IS VALID
             ORG      TABLE+C’S’
             DC       C’Y’        ANY NONZERO VALUE IS VALID
             ORG
   STRING1   DC    X’DOGS*****’    
   STRING2   DC    X’*SSS’
   STRING3   DC    X’CATS’
   STRING4   DC    X’ABCDEFGHIJKLM’
                   ...             Result:

http://csc.columbusstate.edu/woolbright/TRT.HTM[9/21/2011 4:23:23 PM]


trt
Contents
             TR    STRING1,TABLE   R1 POINTS AT “S” IN STRING1
                                   R2 POINTS AT “Y” IN TABLE
                                   CONDITION CODE = MINUS
             TR    STRING2,TABLE   R1 POINTS AT “*” IN STRING1
                                   R2 POINTS AT “X” IN TABLE
                                   CONDITION CODE = MINUS
             TR    STRING3,TABLE   R1 POINTS AT “S” IN STRING1
                                   R2 POINTS AT “Y” IN TABLE
                                   CONDITION CODE = POSITIVE
             TR    STRING4,TABLE   R1 AND R2 ARE UNCHANGED
                                   CONDITION CODE = ZERO

 
1.  TRT can be used to test a field for numeric data (X’F0’ - X’F9’) by using the following table.
            
            TABLE       DC    256X’FF’
                        ORG   TABLE+X’F0’
                        DC    10X’00’     10 DIGITS OCCUR IN ORDER
                        ORG  
 
   Suppose we want to test a field called “FIELD” to see if it is numeric in the sense described above.  This can be accomplished as
follows.
 
                        TRT   FIELD,TABLE   
                        BZ    ALLNUMS      
 
If all the bytes in “FIELD” are numeric, they will be translated to table bytes that contain zeros and the condition code is set to
zero.  If a nonzero byte is found, the condition code is either minus or positive and the branch is not taken.
 
   This technique can be used to verify that a field contains only characters from a given subset.

http://csc.columbusstate.edu/woolbright/TRT.HTM[9/21/2011 4:23:23 PM]


unpack
Contents

 
   UNPK is a SS 2 instruction which is designed to convert data from a packed format to a zoned decimal format.  The operation
proceeds by transferring the contents of operand 2 to operand 1.  Bytes in Operand 1 and 2 are referenced from right to left within
the fields.  The rightmost byte of operand 2 is referenced first, and the zone and numeric parts of the byte are reversed and placed
in the rightmost byte of operand 1.  The next byte (moving right to left) in Operand 1 is processed by taking it numeric part,
prefixing it with bits 1111, and storing it in the next byte (moving right to left) of Operand 1.  Similarly the zone portion of the byte
is prefixed with bits 1111 and stored in the “next” byte of Operand 1.  This process of splitting the zone and numeric portions of a
byte and prefixing them with bits 1111 continues with all subsequent bytes in Operand 2.  The process is terminated (with possible
truncation) if Operand 1 becomes filled.  Keep in mind that the lengths of both operands are provided in the instruction since it has
an SS 2 format.  If all the bytes in Operand 2 are processed and there are bytes remaining in Operand 1, the bytes are filled with
X’F0’s. If Operand 1 is filled before processing all the bytes in Operand 2, high-order truncation of the value in Operand 1 will
occur.
 
The example below illustrates this idea.  The first field, APK, contains packed decimal data, while the second field, AZONED, shows
the results of executing the code below.
 
                         UNPK   AZONED,APK
 
 We assume the following definitions,
 
 
                       APK        DC    PL4’7893023’
                       AZONED     DS    ZL7
 

                        
 
  Since UNPK is SS 2 , each operand contributes a 4-bit length which is stored in the second byte of the object code as pictured at
the top of this page.  The maximum length in the object code is B’1111’ = 15.  Since the assembler always decrements lengths by
1, packed fields are limited to a maximum of 16 bytes.  It is also important to note that the lengths of both fields are used to
execute this instruction.  For instance, if AZONED were defined as ZL3, the high-order digits in the packed field (those on the left)
are truncated in the result.  Consider execution of the the following instruction.
 
 
                       UNPK    AZONED,APK
 
We assume the following definitions,
 
            APK       DC    PL6’7893023’
            AZONED    DS    ZL4
 
 

http://csc.columbusstate.edu/woolbright/UNPK.HTM[9/21/2011 4:23:24 PM]


unpack
Contents

                     
 
The rightmost bytes of APK  are processed and placed in AZONED.  When this field is full, the remaining bytes in APK are
truncated.
 
On the other hand,  if there are too few bytes in operand 2, zeros will be padded on the left in operand 1 as illustrated below. 
Assume the following declarations,
 
                        APK     DC  P’ ’
                        AZONED  DS  ZL6
 
Suppose we execute the following instruction.
 
                       UNPK    AZONED,APK   
 

             
 
All the bytes of APK are processed and fill up five of the bytes in AZONED.  Since AZONED was defined as a seven byte field, the
leftmost 2 bytes are padded with X’F0’s.
 
 

          Some Unrelated UNPK’s:


 
 A          DC      P’12345’      = X’12345C’
 B          DC      PL3’-3’       = X’00003D’
 N          DS      ZL7    
 P          DS      ZL5
 Q          DS      ZL3
 R          DS      ZL2
 
            UNPK    N,A        P = X’F0F0F1F2F3F4C5’  ZERO PADDING
            UNPK    P,A        P = X’F1F2F3F4C5’
            UNPK    Q,A        Q = X’F3F4C5’  LEFT TRUNCATION
            UNPK    N,B        N = X’F4C5’    LEFT TRUNCATION

 
1.  UNPK will operate on any kind of data.  That does not mean that you will like the results.  It simply means that the program will
not abend because of the data contents in a field you unpacking.
 
2.  Use ED or EDMK to convert data to a printable format.  UNPK leaves packed data in a format that is not acceptable for
printing.  For example, consider unpacking XPK into XZONE.
 
                  XPK   DC   P’15’    XPK = X’015C’
                  XZONE DS   ZL3
 
After executing  “UNPK  XZONE, XPK”, XZONE contains X’F0F1C5’.  When printed the field would appear as 01E, since X’C5’ is

http://csc.columbusstate.edu/woolbright/UNPK.HTM[9/21/2011 4:23:24 PM]


unpack
Contents
equivalent to a character E.  
 
 

http://csc.columbusstate.edu/woolbright/UNPK.HTM[9/21/2011 4:23:24 PM]


EXCLUSIVE OR
Contents

 
 
   The Exclusive Or instruction performs a logical bit by bit “exclusive or” between a register and a fullword in memory.  Operand 1,
the target,  is a register and Operand 2, the source, specifies a fullword in memory.  The fullword in memory is exclusive or-ed
internally with the fullword in the register and the result is placed in the register.  The fullword in memory is not changed.  The
table below shows the results of “exclusive or-ing” two bits together.
 
                                                      Bit 1      Bit 2    Result
                                                         0           0            0
                                                         0           1            1
                                                         1           0            1
                                                         1           1            0
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Exclusive Ors


 
              R4 =  X’FFFFFFFF’   ALL 1’S
              R5 =  X’00000000’   ALL 0’S
              R6 =  X’0000148C’   00000000000000000001010010001100
  
              FIELD1  DC   X’0000148C’
              FIELD2  DC   X’00000000’
              FIELD3  DC   X’FFFFFFFF’
              FIELD4  DC   X’12345678’
 
              X    R4,FIELD1    R4 = X’FFFFEB73’ Condition Code = 1
              X    R4,FIELD2    R4 = X’FFFFFFFF’ Condition Code = 1
              X    R4,FIELD3    R4 = X’00000000’ Condition Code = 0
              X    R4,FIELD4    R4 = X’EDCBA987’ Condition Code = 1
              X    R5,FIELD1    R5 = X’0000148C’ Condition Code = 1
              X    R5,FIELD2    R5 = X’00000000’ Condition Code = 0
              X    R5,FIELD3    R5 = X’FFFFFFFF’ Condition Code = 1
              X    R5,FIELD4    R5 = X’12345678’ Condition Code = 1
              X    R6,FIELD1    R6 = X’00000000’ Condition Code = 0
              X    R6,FIELD2    R6 = X’0000148C’ Condition Code = 1
              X    R6,FIELD3    R6 = X’FFFFEB73’ Condition Code = 1
              X    R6,FIELD4    R6 = X’123442F4’ Condition Code = 1

http://csc.columbusstate.edu/woolbright/EXOR.HTM[9/21/2011 4:23:25 PM]


EXCLUSIVE OR CHARACTER
Contents

 
 
   The Exclusive Or Character instruction performs a logical bit by bit “exclusive or” between two fields in memory. Operand 1, the
target,  is a memory field and Operand 2, the source, also specifies a storage location in memory.  The number of characters which
participate in the operation is determined by the first operand, and as a result, is limited to 256 bytes.  The storage fields are
exclusive or-ed internally with the result placed in the target field. Typically, the source is unaffected, but can be altered by this
operation if the fields overlap.  The table below shows the results of “exclusive or-ing” two bits together.
 
                                                       Bit 1      Bit 2    Result
                                                          0           0            0
                                                          0           1            1
                                                          1           0            1
                                                          1           1            0
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Exclusive Or Characters


 
              FIELD1  DC   X’0001020304’
              FIELD2  DC   X’FFFFFF’
              FIELD3  DC   C’ABC’
              FIELD4  DC   X’000000’
 
     XC    FIELD1,FIELD1    FIELD1 = X’0000000000’ Condition Code = 0
     XC    FIELD2,FIELD1    FIELD2 = X’FFFEFD’     Condition Code = 1
     XC    FIELD3,FIELD1    FIELD3 = X’C1C3C1’     Condition Code = 1
     XC    FIELD2,FIELD3    FIELD2 = X’3E3D3C’     Condition Code = 1
     XC    FIELD3,FIELD3    FIELD3 = X’000000’     Condition Code = 0
     XC    FIELD3,FIELD4    FIELD3 = X’C1C2C3’     Condition Code = 1
     XC    FIELD1+2,FIELD3  FIELD1 = X’0001C3C1C7’ Condition Code = 1
     XC    FIELD1(3),FIELD2 FIELD1 = X’FFFEFD0304’ Condition Code = 1
 
 
 
 
 
 
 
 

   The XC instruction is occasionally used to clear a character field by exclusive or-ing it with itself:
                XC    FIELDA,FIELDA
 
The result is a field that contains binary 0’s.  If the field is printed, it will appear as sequence of blanks since binary 0’s are
unprintable.  While this technique may work for reports, keep in mind that binary 0’s are not blanks.  If you need blanks, the
following code might be used:
 
            MVI    FIELDA,C’ ’         MOVE THE 1ST BLANK
            MVI    FIELDA+1(L’FIELDA-1),FIELDA  MOVE THE OTHER BLANKS

http://csc.columbusstate.edu/woolbright/EXORCHAR.HTM[9/21/2011 4:23:26 PM]


EXCLUSIVE OR IMMEDIATE
Contents

                                                  
  
 
   The Exclusive Or Immediate instruction performs a logical bit by bit “exclusive or” between a byte in memory  and an immediate
constant.  Operand 1, the target,  is a byte in memory and Operand 2, the source, specifies the immediate constant.  The byte in
memory is exclusive or-ed internally with the immediate constant and contains the final result.  The immediate constant is not
changed.  The table below shows the results of “exclusive or-ing” two bits together.
 
                                                 Bit 1      Bit 2    Result
                                                    0           0            0
                                                    0           1            1
                                                    1           0            1
                                                    1           1            0
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Exclusive Or Immediates


 
              BYTE1  DC   X’00’
              BYTE2  DC   X’FF’
              BYTE3  DC   X’C3’
 
       XI    BYTE1,X’12’         BYTE1 = X’12’    Condition Code = 1
       XI    BYTE1,X’FF’         BYTE1 = X’FF’    Condition Code = 1
       XI    BYTE1,C’A’          BYTE1 = X’C1’    Condition Code = 1
       XI    BYTE1,B’11110000’   BYTE1 = X’F0’    Condition Code = 1
       XI    BYTE2,X’12’         BYTE2 = X’ED’    Condition Code = 1
       XI    BYTE2,X’FF’         BYTE2 = X’00’    Condition Code = 0
       XI    BYTE2,C’A’          BYTE2 = X’3E’    Condition Code = 1
       XI    BYTE2,B’11110000’   BYTE2 = X’0F’    Condition Code = 1
       XI    BYTE3,X’12’         BYTE3 = X’D1’    Condition Code = 1
       XI    BYTE3,X’FF’         BYTE3 = X’3C’    Condition Code = 1
       XI    BYTE3,C’A’          BYTE3 = X’02’    Condition Code = 1
       XI    BYTE3,B’11110000’   BYTE3 = X’33’    Condition Code = 1

http://csc.columbusstate.edu/woolbright/EXORIMM.HTM[9/21/2011 4:23:27 PM]


OR REGISTER
Contents

                                                              
 
   The Exclusive Or Register instruction performs a logical bit by bit “exclusive or” between two registers.  Operand 1, the target,  is
a register and Operand 2, the source, also specifies a register.  The fullword in Operand 1 is exclusive or-ed internally with the
fullword in Operand 2,  and the result is placed in Operand 1.  The table below shows the results of “exclusive or-ing” two bits
together.
 
                                                       Bit 1      Bit 2    Result
                                                          0           0            0
                                                          0           1            1
                                                          1           0            1
                                                          1           1            0
 
   This instruction sets the condition code as follows:
 
                 0  if all target bits are set to 0.  Test this condition with BZ or BNZ.
                 1  if any target bit is set to 1.  Test this condition with BM or BNM.
 

        Some Unrelated Exclusive Or Registers


 
              R4 =  X’FFFFFFFF’   ALL 1’S
              R5 =  X’00000000’   ALL 0’S
              R6 =  X’0000148C’   00000000000000000001010010001100
              R7 =  X’000014AB’   00000000000000000001010010101011
 
              XR   R4,R4    R4 = X’00000000’ Condition Code = 0
              XR   R4,R5    R4 = X’FFFFFFFF’ Condition Code = 1
              XR   R4,R6    R4 = X’FFFFEB73’ Condition Code = 1
              XR   R4,R7    R4 = X’FFFFEB54’ Condition Code = 1
              XR   R5,R6    R5 = X’0000148C’ Condition Code = 1
              XR   R5,R7    R5 = X’000014AB’ Condition Code = 1
              XR   R6,R7    R6 = X’00000027’ Condition Code = 1
              XR   R7,R7    R7 = X’00000000’ Condition Code = 0

http://csc.columbusstate.edu/woolbright/EXORREG.HTM[9/21/2011 4:23:27 PM]

You might also like