Joined: 24 Jul 2012 Posts: 10 Location: United States
Ok, the assembler novice here again. The program I'm attempting to write is an E15 exit for sort. The input file is variable length. The first 3000 (+RDW) bytes are always present. The final 250 bytes are always the same data area and what is in between varies.
So, I want to move the first 3004 bytes, then calculate where the final 250 bytes begin. Here is what I have so far:
Code:
IMSRTEXB CSECT
SIEQREG
STM R14,R12,12(13)
BASR R12,R0
USING *,R12
ST R13,SAVE+4
LA R14,SAVE SET FORWARD POINTER
ST R14,8(R13) IN SAVE AREA
LR R13,R14 SET OUR SAVE AREA ADDR IN R13
***********************************************************************
* THE PROGRAM RECEIVES THE COMPRESSED IM MASTER FROM SORT AND WILL *
* RETURN THE FIXED PORTION FOLLOWED IMMEDIATELY BY THE DC TRAILER *
***********************************************************************
LR R2,R1 SAVE PARM AREA
L R3,0(,R2) LOAD ADDRESS OF THE PASSED RECORD
LTR R3,R3 CHECK FOR EOF. THE ADDR IS 0
BZ EOF WE ARE DONE
***********************************************************************
* MOVE THE FIXED PORTION OF THE MASTER TO THE OUTPUT AREA
***********************************************************************
LA R6,OFIXEDR
LA R7,3004
LR R8,R3
LA R9,3004
MVCL R6,R8
MVI OFIXEDR+6,C'D'
MVC ODCTR(2),0(R3)
Up this point in the program, things work. I put that move of a "D" to that position so that I could verify that the output was truly being manipulated by this program. It is. So I know I moved the first 3004 bytes of the input to the output and successfully pointed to the output area (which is further down in the program.
So, next I have these statement:
Code:
***********************************************************************
* MOVE THE DC TRAILER AREA NEXT TO OUTPUT FIXE PORTION
***********************************************************************
LH R4,0(,R3) GET INPUT RDW
SH R4,DCLEN SUBTRACT DC LENGTH
STH R4,DCDISP MOVE DC DISPLACEMENT TO DCDISP
STH R4,ODCLEN
LA R10,L'DCDISP(R0,R3) ADDRESS OF INPUT DC TRLR TO R10??
R3 is still the address of the original input record. The first halfword of which is the RDW. But when the LH executes to move the half word at address in R3, it always places zero in R4. Always. At least that is what it appears to do in Xpeditor. I don't understand why this is so. I copied this from other examples.
Thoughts? I will be happy to provide additional information that may be needed.
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
LA R10,L'DCDISP(R0,R3)
I find this confusing. Are you trying to use reg 0 as an index register? I hate tell you, but register 0 cannot be used as either an index register or a base register. R10,L'DCDISP(R0,R3) is usually coded as R10,L'DCDISP(,R3). The generated object code is the same, but it avoids showing R0 as a pseudo index register.
In general, the code you provide cannot be analyzed because the definition for many data areas mentioned in the code is not shown; a prime - though by no means the only example - is DCDISP.
Joined: 24 Jul 2012 Posts: 10 Location: United States
You are right, I failed to respond to the other thread that I had gotten past the 0C4 and I apologize. Someone else looking at my program pointed out that I didn't need the DSECT since my area wasn't over 4096. Sorry to all. I thought it best to begin this thread because the problem had changed. My bad.
And no, I don't expect anyone to be "running around" doing anything. If my posts need more info, I again apologize. If everyone is as busy as I am, I value your time, your experience and knowledge. I wish not to waste anyone's time.
Yes, I am trying to put together a simple E15 exit. I am about to throw it in the trash can but have decided to reach out for some other opinions.
So, I will try to post enough information once again and if I can't get it right, I will just go away.
Code:
IMSRTEXB CSECT
SIEQREG
STM R14,R12,12(13)
BASR R12,R0
USING *,R12
ST R13,SAVE+4
LA R14,SAVE SET FORWARD POINTER
ST R14,8(R13) IN SAVE AREA
LR R13,R14 SET OUR SAVE AREA ADDR IN R13
***********************************************************************
* THE PROGRAM RECEIVES THE COMPRESSED IM MASTER FROM SORT AND WILL *
* RETURN THE FIXED PORTION FOLLOWED IMMEDIATELY BY THE DC TRAILER *
***********************************************************************
LR R2,R1 SAVE PARM AREA
L R3,0(,R2) LOAD ADDRESS OF THE PASSED RECORD
LTR R3,R3 CHECK FOR EOF. THE ADDR IS 0
BZ EOF WE ARE DONE
***********************************************************************
* MOVE THE FIXED PORTION OF THE MASTER TO THE OUTPUT AREA
***********************************************************************
LA R6,OFIXEDR
LA R7,3004
LR R8,R3
LA R9,3004
MVCL R6,R8
MVI OFIXEDR+6,C'D' A TEST TO SEE IF DATA MOVED
***********************************************************************
* MOVE THE DC TRAILER AREA NEXT TO OUTPUT FIXE PORTION
***********************************************************************
LH R4,0(,R3) GET INPUT RDW
SH R4,DCLEN SUBTRACT DC LENGTH
STH R4,DCDISP MOVE DC DISPLACEMENT TO DCDISP
LA R10,L'DCDISP(R0,R3) ADDRESS OF INPUT DC TRLR TO R10??
***********************************************************************
LA R6,ODCTR POINT TO OUTPUT DC TRLR
LH R7,DCLEN LENGHT OF MOVE
LR R8,R10 POINT TO INPUT DC TRLR
LH R9,DCLEN LENGTH OF MOVE
MVCL R6,R8 MOVE DCTRLR TO OUTPUT
***********************************************************************
HEADHOME EQU *
LA R1,OFIXEDR POINT R1 TO OUTPUT RECORD
SR R15,R15 SET RC=0
B GOBACK
EOF DS 0H
L R15,8 SET RC=8
GOBACK DS 0H
L R13,4(,R13) POINT TO BACKWARD POINTER
L R14,12(,R13) RESTORE R14
LM R2,R12,28(R13) RESTORE R2 - R12
BR R14 GO BACK
SAVE DS 18F
DCDISP DS H
FXLEN DS H'3004'
DCLEN DS H'250'
OFIXEDR DS 0H
OFXRDW DS H
DC H'0'
OFIXED DS CL3000
ODCTR DS 0C
ODCLEN DS H
ODCDATA DS CL248
END IMSRTEXB
So, as I tried to describe earlier, the move of the first 3004 bytes is OK. I tested this by branching from there to the HEADHOME and sort got that data back ok.
It is when I get to the LH R4,0(,R3) that things seem to go south. It seems that R4 gets a value of zero.
Steve, to answer you about the LA R10,L'DCDISP(R0,R3), I am grasping at straws here. The goal was to calculate the displacement from the beginning of the variable input record where this final 250 bytes begins. What I was attempting here is this:
Put the input record length into R4
Subtract the length of the final trailer, which is DCLEN, 250
Now, put that new value in R4.
Store that displacement value in DCDISP
Load into R10 the address at the displacement DCDISP off of R3,which is where the original input record is it. As for the base register R0, I realize that. I think I saw that in some stuff I was reading and used it. I understand it really contributes nothing here.
If I had successfully be able to get the adresss of the final 250 bytes, I have coded a MVCL to use that address. I also realize now as I type this that I don't need MVCL to move this 250 bytes, but that is what I have at the moment.
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Doug,
If you plan on using labels FXLEN and DCLEN and their defined values, note that they are DS (Define Storage) and their values will be X'00's.
Instead, define them as DC (Define Constant) and you'll be good to go.
The following will work -
Code:
FXLEN DC AL2(L'OFIXED+4) WILL YIELD H'3004'
DCLEN DC AL2(L'ODCDATA+2) WILL YIELD H'250'
Regarding your other predicament, are you sure that the RDW at 0(,R3) that you're loading into R4 is a halfword? Maybe it's a fullword, in which case, change your LH to an L.
Joined: 24 Jul 2012 Posts: 10 Location: United States
R3 still have the address of the input record, which is variable length. I used fileaid to do a hex dump of the file, here is the first record. The first 2 bytes is the length of the record. That's why I'm thinking halfword here.
Code:
F I L E - A I D V9.3.1 25 - MAR - 2014 07.05.25 PAGE 1
DD01=IMTD.DSA.PSM.IMACTM.RECS2000 VOL=BTLV24
REC 1 DATA 8215 CHAR 02000000000000010000181 00000001 000001 0
01801-00-001 DATA27998 ZONE 2100FFFFFFFFFFFFFFFFFFFFFFF44444444444444FFFFFFFF4FFFFFF44F44444444444444444444
NUMR 0700020000000000000100001810000000000000000000001000000100000000000000000000000
1...5...10...15...20...25...30...35...40...45...50...55...60...65...70...75...8
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
Quote:
The first 2 bytes is the length of the record. That's why I'm thinking halfword here.
A Record Descriptor Word (RDW) is actually 4 bytes -- the last two bytes will be zero unless the data set is Variable Spanned (VS or VBS). Using a halfword for the length is correct, but make sure you don't try to treat the next two bytes as part of the record as they are not.
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
Robert Sample wrote:
Quote:
The first 2 bytes is the length of the record. That's why I'm thinking halfword here.
A Record Descriptor Word (RDW) is actually 4 bytes -- the last two bytes will be zero unless the data set is Variable Spanned (VS or VBS). Using a halfword for the length is correct, but make sure you don't try to treat the next two bytes as part of the record as they are not.
The only time a programmer need be concerned about the second 2 bytes in an RDW is if he is reading or writing a VS or VBS data set using BSAM and has to manually construct the record segments. A program using GET or PUT macros with a DCB that specifies BFTEK=A need not be concerned. In the last two years I've written several programs that process SMF data and never once worried about the mechanics of spanned records.