OPCODE: BXLE Part 2 (analyzing PARM text)



High Level Assembler(HLASM) for MVS & VM & VSE

OPCODE: BXLE Part 2 (analyzing PARM text)

Postby steve-myers » Sat Jul 06, 2013 11:22 am

Our sister site, http://ibmmainframes.com has a very confused Cobol programmer who does not understand that while parameter text may be specified in JCL as containing many substrings, it is the responsibility of the programmer to separate the substrings.

The following program does just that, but it just lists each substring to SYSPRINT. For this program, the data set contains variable length records.
LISTPARM CSECT
         USING *,12
         SAVE  (14,12),,*
         LR    12,15
         LA    15,SAVEAREA
         ST    13,4(,15)
         ST    15,8(,13)
         LR    13,15
         L     2,0(,1)
         OPEN  (PRINT,OUTPUT)
         LH    5,0(,2)
         LTR   5,5
         BP    SCAN0100
         PUT   PRINT,MSG01
         B     EXIT
SCAN0100 LA    5,1(5,2)
         LA    4,1
         LA    3,2(,2)
         LA    6,1
SCAN0200 LR    0,3
SCAN0300 CLI   0(3),C','
         BE    SCAN0400
         BXLE  3,4,SCAN0300
SCAN0400 LR    1,3
         SR    1,0
         BP    SCAN0500
         CVD   6,DWORK
         OI    DWORK+L'DWORK-1,X'0F'
         UNPK  PARMNO,DWORK
         MVC   PARMTEXT(4),=C'NULL'
         LA    14,PARMTEXT+4
         B     SCAN0600
SCAN0500 LA    14,PARMTEXT
         LR    15,1
         MVCL  14,0
         CVD   6,DWORK
         OI    DWORK+L'DWORK-1,X'0F'
         UNPK  PARMNO,DWORK
SCAN0600 LA    1,MSG02
         SR    14,1
         STH   14,0(,1)
         PUT   PRINT,MSG02
         LA    6,1(,6)
         BXLE  3,4,SCAN0200
EXIT     CLOSE PRINT
         L     13,4(,13)
         RETURN (14,12),T,RC=0
SAVEAREA DC    9D'0'
DWORK    DC    D'0'
PRINT    DCB   DSORG=PS,MACRF=PM,DDNAME=SYSPRINT,RECFM=VBA,LRECL=125
MSG01    DC    AL2(MSG01L,0),C' NO PARAMETER TEXT WAS SENT'
MSG01L   EQU   *-MSG01
MSG02    DC    AL2(*-*,0),C' PARAMETER '
PARMNO   DC    CL2' ',C' IS '
PARMTEXT DC    CL(125-(*-PARMTEXT))' '
         DC    0D'0'
         LTORG ,
         END   LISTPARM


USING *,12
SAVE (14,12),,*
LR 12,15
LA 15,SAVEAREA
ST 13,4(,15)
ST 15,8(,13)
LR 13,15

The preceding code is the usual Assembler entry code that
  1. Saves the caller's registers in the save area the caller must provide,
  2. Copies the entry point address the caller supplies in register 15 to register 12 to provide addressability for our program.
  3. And prepares a new save area so our program can call other programs.

L 2,0(,1)
OPEN (PRINT,OUTPUT)

When our program is called, register 1 points to a parameter list. Since the OPEN macro destroys register 1, our program loads the parameter list into register 2 before it opens the output data set.

LH 5,0(,2)
LTR 5,5
BP SCAN0100
PUT PRINT,MSG01
B EXIT

The parameter list points to a 2 byte data are that contains the length of the parameter text. If the JCL did not specify any text, this length field is 0, and we write an error message.

LA 5,1(5,2)
LA 4,1
LA 3,2(,2)
LA 6,1

This code prepares the registers used to scan the parameter text. Register 5 contains the address of the last byte in the parameter text, register 4 is set to 1, register 3 points to the address of the first byte in the parameter text, and register 6 contains the initial parameter number.

SCAN0200 LR 0,3
SCAN0300 CLI 0(3),C','
BE SCAN0400
BXLE 3,4,SCAN0300

The LR at SCAN0200 copies the start of the current substring to register 0. The code starting at SCAN0300 locates the end of a substring.

SCAN0400 LR 1,3
SR 1,0
BP SCAN0500

The code at SCAN400 copies the end of the substring to register 1 and computes the length of the substring. If the length of the substring is not 0, the code branches to SCAN0500.

CVD 6,DWORK
OI DWORK+L'DWORK-1,X'0F'
UNPK PARMNO,DWORK
MVC PARMTEXT(4),=C'NULL'
LA 14,PARMTEXT+4
B SCAN0600

The code converts the contents of register 6 to a decimal valu and stpres it in the PARMNO data area in the MSG02 message area, then it copies the word NULL to the PARMTEXT area in the message area and sets register 14 to the address of the end of the NULL text.

SCAN0500 LA 14,PARMTEXT
LR 15,1
MVCL 14,0
CVD 6,DWORK
OI DWORK+L'DWORK-1,X'0F'
UNPK PARMNO,DWORK

If you haven't noticed this already, registers 0 and 1 are an even/odd register pair for the second operand of the MVCL instruction. Starting at SCAN0500 the program prepares registers 14 and 15 to be the even/odd register pair for the first operand of an MVCL instruction. The MVCL instruction copies a substring from the parameter text to the output message. Finally, the program converts register 6 to a number starting at PARMNO in the message.

SCAN0600 LA 1,MSG02
SR 14,1
STH 14,0(,1)
PUT PRINT,MSG02

When the program arrives at SCAN0600, register 14 points to the end of the message, so the progran compute the length of the message and stores the message length in the RDW starting at MSG02, and the writes the message.

LA 6,1(,6)

Update the parameter counter in register 6.

BXLE 3,4,SCAN0200
Register 3 points tp the comma at the end of the substring, or it points to the end of the parameter text. This BXLE updates register 3 to point to the first byte in the next substring, and branches if there is more text in the parameter text. If the BXLE does not branch. the program has completed the parameter text scan.

EXIT CLOSE PRINT
L 13,4(,13)
RETURN (14,12),T,RC=0

Close the data set, load the address of the higher save area from the current save area, and restore the registers and return to our caller.

SAVEAREA DC 9D'0'

This is the register save area used by any programs our program calls. The PUT macro, in essence, calls a subroutine to copy a message to a real I/O buffer.

DWORK DC D'0'

This instruction defines an 8 byte work area used by the CVD and UNPK instructions in the program. Technically, a data area specifies as type D is a hexadecimal floating point number, but in our program the data area will contain a packed decimal number.

PRINT DCB DSORG=PS,MACRF=PM,DDNAME=SYSPRINT,RECFM=VBA,LRECL=125

The DCB macro defines a relatively large (96 byte) data area called a DCB.

DSORG=PS specifies a DCB for a sequential data set is being created.

MACRF=PM specifies that the PUT macro using "move" processing is being used with this data set. The program provides a complete message.

DDNAME=SYSPRINT specifies that a data set specified by a DD statement with DD name SYSPRINT will be used for the I/O .

MSG01 DC AL2(MSG01L,0),C' NO PARAMETER TEXT WAS SENT'
MSG01L EQU *-MSG01

These instructions define a message in the variable length message format The first 4 bytes in the MAG01 data area specify a data area called an RDW that contains the message length.

MSG02 DC AL2(*-*,0),C' PARAMETER '
PARMNO DC CL2' ',C' IS '
PARMTEXT DC CL(125-(*-PARMTEXT))' '

These instructions define a message skeleton area. The PARMTEXT area fills out a data area for the maximum possible message. The actual message length is stored in the RDW data area just before the message is sent to the I/O buffer by the PUT macro.

DC 0D'0'
LTORG ,
END LISTPARM

The LTORG Assembler instruction tells the Assembler program to insert the data specified by literals here. The Assembler aligns this data area on a double word boundary; the DC instruction just before the LTORG instruction effectifvely tells the Assembler prgram to insert binary 0s to fill out to a double word boundary

These users thanked the author steve-myers for the post (total 5):
Peter_Mann (Wed Aug 28, 2013 9:05 pm) • dick scherrer (Sat Jul 06, 2013 11:42 pm) • Akatsukami (Sat Jul 06, 2013 7:28 pm) • NicC (Sat Jul 06, 2013 3:22 pm) • BillyBoyo (Sat Jul 06, 2013 1:19 pm)
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: OPCODE: BXLE Part 2 (analyzing PARM text)

Postby steve-myers » Sun Jul 07, 2013 9:21 am

There is a minor error in the LISTPARM program. It does not affect program execution.
MSG02    DC    AL2(*-*,0),C' PARAMETER '
PARMNO   DC    CL2' ',C' IS '
PARMTEXT DC    CL(125-(*-PARMTEXT))' '

The intended purpose of 125-(*-PARMTEXT) was to provide a data area that is just long enough to define the storage for a maximum length record. The 125, of course, is the LRECL specified in the PRINT DCB. However, the data area is too long. The formula should be 125-(*-MSG02). The *-MSG02 defines the length of the RDW, and the PARAMETER nn IS text in the line.

The LISTPARM program does not verify the parameter text will fit in the available space. This is never a problem if LISTPARM is called from JCL since the maximum length of the text in PARM='parameter text' is 100 bytes; even with the correction, the length of the PARMTEXT data area is 104 bytes, but it could be a problem if LISTPARM is called from another program.
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times

Re: OPCODE: BXLE Part 2 (analyzing PARM text)

Postby bobguo » Wed Aug 28, 2013 10:07 am

first of all, thank you very much for your detailly analysis.

MSG02    DC    AL2(*-*,0),C' PARAMETER '


*-* is always 0, so why using *-* instead of 0?
as you said, *-* stands for RDW, can you tell me what RDW stands for?
besides, i am just interested in why the second half word of AL2(*-*,0) is always 0? it looks very like WTO buffer.
bobguo
 
Posts: 76
Joined: Thu Apr 26, 2012 11:18 am
Location: shanghai
Has thanked: 22 times
Been thanked: 0 time

Re: OPCODE: BXLE Part 2 (analyzing PARM text)

Postby steve-myers » Wed Aug 28, 2013 11:05 am

*-* is always 0, so why using *-* instead of 0?
I generally use *-* to indicate a data area that will be modified. I started out using the IBM 7040. The programming convention was to use ** for this purpose. The 7040 Assembler considered this to be * (the location counter) * (multiply by) [nothing, or 0]. The System/360 Assemblers would not take ** interpreted the same way as the old Assemblers, so the convention grew up to use *-*.
can you tell me what RDW stands for?
Record Descriptor Word, as used in data sets with variable length records.
i am just interested in why the second half word of AL2(*-*,0) is always 0? it looks very like WTO buffer
You are correct. Early System/360 machines had a single printer/keyboard, and the WTO macro just generated a VB style data area. By the late 1960s the machines had more consoles, and there was a requirement to route messages more finely, so the ROUTCDE and DESC operands were added to the WTO macro to describe the intended generic location of the message, and the second 2 bytes of the message were made flags. There was also a mechanism to route a message to a specific console, though that mechanism no longer works because the requirement became more generalized. Now it is possible for an appropriately authorized TSO user to submit an operator command from his TSO session and receive the response at his terminal, which was not possible using the old QREG0 interface.

I believe the System/360 Model 85 was the first System/360 that did not have a printer/keyboard style operator console; the primary operator console was a very unusual graphics console coupled with what seemed like a keypunch keyboard. With minor changes this operator console became the primary operator console of the System/370 Models 165 and 168.

These users thanked the author steve-myers for the post (total 2):
Peter_Mann (Wed Aug 28, 2013 9:07 pm) • bobguo (Wed Aug 28, 2013 12:00 pm)
steve-myers
Global moderator
 
Posts: 2105
Joined: Thu Jun 03, 2010 6:21 pm
Has thanked: 4 times
Been thanked: 243 times


Return to Assembler

 


  • Related topics
    Replies
    Views
    Last post