The STRING Macro Instruction for S/370 and S/390 Assembler

                 

The STRING assembler macro instruction provides functionality similar to the COBOL DISPLAY or PL/I PUT EDIT instructions. STRING can be used in environments which support Assembler H or the High-Level Assembler, i.e. MVS, OS/390, z/OS, VSE/ESA, z/VSE and VM/CMS. MVS users may obtain the STRING macro from the freeware section of this Web site. VSE and VM users can find it here.

Using STRING, the programmer can concatenate any number of fields and constants, convert each of them to printable format if necessary, and store the result into the specified output area. STRING is designed for easy implementation in re-entrant and non-reentrant programs. In particular, STRING uses the second half of the standard save area supplied by the caller for data editing, and does not require a separate work area. For additional information, please read the Programming Notes at the end of this page.

The STRING macro requires Assembler H (with or without the SLAC Mods), or the High-Level Assembler and only supports AMODE=24 and AMODE=31 programs. However, there are two alternative versions of the macro that provide the same functional capabilities in different environments:

  1. STRING64 supports AMODE=64 programs in z/OS and is used over 3000 times in current versions of the SHOWzOS program. STRING64 and SHOWzOS are distributed in file 492 of the CBT tape.
  2. STRINGXF is compatible with the Assembler XF on OS/VS systems. STRINGXF is distributed in the OSVS238J package on this site.

Release 203 of STRING which dates back to March 1989 is available here. It's the oldest version I was able to find in my archives.

           

Syntax

The syntax of the STRING macro is described below. Coding examples are available later in this document, and here.

     (1) label  STRING {field_specification1}
                      {,field_specification2}...
                      ,INTO=output_area|(output_area,length)
                      {,PRINT=GEN|NOGEN}

     (2) label  STRING GENERATE
                      {,PRINT=GEN|NOGEN} 

field_specification

Each field to be printed is described as a positional operand. Each operand specifies the field address, its length, and its formatting requirements.

Four field description formats are supported:

  1. symbol
  2. (symbol,length,format)
  3. (d(r)|(r),length,format)
  4. ((r),,format)
  5. 'character string'

Symbol specifies the field address. It must be an S-type (relocatable) address.

d(r) may be used to specify the field address in S/370 base-displacement format. If d is zero, it may be omitted. If d(r) or (r) is used, length must also be specified. R14 and R15 may not be used. If d(0) is used, it is handled the way the assembler does, i.e. R0 as a base register is assumed to contain zero: 16(0) is equivalent to 16, CVTPTR or, X'10'.

((r),,format) specifies that (r) contains the value itself, not an address. R14 and R15 may not be used.

'character string' specifies a literal enclosed in single quotes as specified in a DC instruction. Hex strings or character strings are supported. The following expressions are equivalent: 'ABC' C'ABC' X'C1C2C3'

Length specifies the length and/or the type of the input field. It may be specified as an integer, a symbol, a register, or a constant. When used with symbol, it overrides the assembled length and/or type. Length is required if field is specified as d(r) or (r). If a zero length is specified, the field is ignored. Length can be specified as follows:

Notes:

Format optionally indicates editing options that must be applied to a field.

	L	left justified
	R	right justified
	nn	output length
	0	adjust length
	Z	leading zeroes
	B	leading/trailing blanks
	T	truncate character string after last non-blank
	X	display in hexadecimal
	YYMMDD	convert julian date to YYMMDD
	YY/MM/DD convert julian date to YY/MM/DD
	DD/MM/YY convert julian date to DD/MM/YY
	MM/DD/YY convert julian date to MM/DD/YY
	YYYYMMDD convert julian date to YYYYMMDD
	YYYY-MM-DD convert julian date to YYYY-MM-DD 

The default format depends on the field type:

	Type			  Default Format

	character string		L
	FL1				R3B
	H or FL2			R5B
	other numeric fields		R7B 

Note: either L0 or T can be specified to truncate character string after last non-blank character, i.e. to drop trailing spaces.

'character string' is any character string enclosed in single quotes. Blank spaces may be specified as nnX, where nn is the number of X'40' bytes you want to insert in the output line. For example, STRING '12345',3X,'67890',INTO=XXX concatenates '12345', 3 spaces, '67890', and trailing spaces into the output field. It is equivalent to this: STRING '12345   67890',INTO=XXX.

On MVS systems, %TIME may be specified to obtain the current time in hh:mm:ss.hh format. By default, the length of the generated field is 12 bytes, i.e. hh:mm:ss.hh plus a trailing space. The length may be specified in (%TIME,length) to truncate the field to the first 5, 8 or 11 bytes of the generated field; for example, when (%TIME,8) is specified, an 8-byte field which contains hh:mm:ss is generated. (%TIME,length) is only supported in STRING R518 and above.

On VSE systems, %TIME may also be specified if the TIME macro is available (VSE/ESA 2.4 and above); if the TIME macro is not available in VSE, %TIME should not be used, unless the STRING macro is modified to use GETIME instead of TIME.

INTO=output_area|(output_area,length)

PRINT=GEN|NOGEN

GENERATE (format 2)

The GENERATE format must be specified once at the end of the program. It generates the @STRING sub-routine as well as all the literals specified in previous invocations of the macro.

The GENERATE format allows the specifications of the AR_MODE, NO_CSECT and LOCTR options.

	STRING GENERATE<,AR_MODE>,LOCTR>>>
			NO_CSECT 

The following combinations are valid:

	STRING GENERATE
	STRING (GENERATE,NO_CSECT)
	STRING (GENERATE,AR_MODE)
	STRING (GENERATE,,LOCTR)
	STRING (GENERATE,AR_MODE,LOCTR) 

The AR_MODE option can be specified to generate a @STRING module that supportd AR mode. Example:

	STRING (GENERATE,AR_MODE) 

The NO_CSECT option can be specified to indicate that the @STRING module should not be generated; only the literals are generated in this case. Example:

	STRING (GENERATE,NO_CSECT) 

The @STRING CSECT contains optional functions (such as %TIME or julian date conversion) that are only generated if they have been specified in the previous invocations of the STRING macro.

To generate an @STRING CSECT that supports all of the optional functions, two STRING GENERATE macros must be specified:

	STRING (GENERATE,NO_CSECT)        Generate Literals
	STRING GENERATE                   Generate full-function CSECT 

When several programs that use the STRING macro are link-edited together, only the first @STRING CSECT is present in the load-module. This may result in some of the necessary optional functions to be unavailable, and cause some of the sub-programs to produce incorrect output. There are several simple solutions to this problem:

  1. In the first module, specify the two   STRING GENERATE   macros shown in the example above.
  2. Specify   STRING (GENERATE,NO_CSECT)   in each module and run this job to create a separate load-module which contains a complete @STRING CSECT
  3. Specify   STRING (GENERATE,,LOCTR)   in each module

Examples:

	STRING 1X,INTO=BLANKS		blank out the BLANKS area
	.	.
 BLANKS DS    CL10000

	STRING 'ERROR===>',LINE1,'<=== POS ',((R6),,L0),INTO=output_area

	STRING (DSN44,,T),INTO=DSN44	calc length of DSN (no trailing blanks)
	LR    R5,R15			pass length 
	.	.
 DSN44	DC    CL44'USER.SAMPLIB'	data set name

	STRING 8X,C'ERRORS FOUND: ',(ERRORS,,L0),INTO=(4(R7),44)
	ST    R15,0(,R7)		store length

	STRING 'CVT ADDR IS ',(CVTPTR,4,X),X'40C1C2C3C4',		X
	      INTO=LINE

	L     R4,CVTPTR(0,0)		CVT address
	USING CVTMAP,R4
	STRING 'Today is ',(CVTDATE,P,YYYY-MM-DD),INTO=(LINE,32)

	LA    R5,WORK+16		end addr +1
	STRING 'R4=',((R4),,X),INTO=(WORK,(R5)),PRINT=GEN

	STRING '//JOBLIB DD DSN=',(DSN1,,T),',DISP=SHR',INTO=((R2),72)

	PUT   SYSLIN			PUT Locate
	LH    R0,SYSLIN+82		LRECL
	STRING '   NAME  ',(4(R3),8,T),'(R)',INTO=((R1),(R0))

	RDJFCB SYSUT2 
	STRING '0',%TIME,'SYSUT2 OUTPUT: ',JFCBDSNM,1X,(JFCBVOLS,6),	X
	      INTO=LINE121 
	PUT   SYSPRINT,LINE121

	STRING ' hh:mm:ss=',(%TIME,8),INTO=LINE121 
	PUT   SYSPRINT,LINE121

	STRING GENERATE 		Generate literals and sub-routine 

R516 of the STRING macro provides two enhancements which are shown in the example below:

         BAKR  R14,0
         BALR  R12,0
         USING *,R12
         OPEN  (SYSPRINT,OUTPUT)
         STRING 'R12=',((R12),,X),'   16(R12)=',(16(R12),4,X),INTO=XXX
         PUT   SYSPRINT,XXX
         CALL  TCSECT2              <- 2nd CSECT
         CALL  TCSECT3              <- 3rd CSECT
         SLR   R15,R15
         PR
*
SYSPRINT DCB   DSORG=PS,DDNAME=SYSPRINT,MACRF=PM,RECFM=FB,LRECL=121
XXX      DS    CL121
*
TCSECT2  CSECT
         BAKR  R14,0
         LR    R10,R15
         USING TCSECT2,R10
         STRING '----> TCSECT2 STRING <----  R516',INTO=XXX
         PUT   SYSPRINT,XXX
         L     R1,16(0,0)
         STRING 'CVTDATE=',(56(R1),4,X),',R8=',((R8),,L),INTO=XXX
         PUT   SYSPRINT,XXX
         PR
*
	 CSECT					CSECT with NO-NAME
TCSECT3  BAKR  R14,0
         LR    R10,R15
         USING TCSECT3,R10
         L     R1,16(0,0)
         STRING 'CVTDATE=',(56(R1),4,X),',R9=',((R9),,L),INTO=XXX
         PUT   SYSPRINT,XXX
         STRING '----> TCSECT3 STRING <----  R516',INTO=XXX
         PUT   SYSPRINT,XXX
         PR
*
         STRING GENERATE
         YREGS
         END 

Programming Notes

Search key-words: ibm 370 390