Page 2 of 2

Re: I can't get the LINK macro working properly

PostPosted: Wed Aug 26, 2020 12:58 pm
by chong_zhou
steve-myers wrote:The macro itself did not calculate the +20. Some anonymous IBM programmer in the 1960s calculated the +20.


Haha! :D

Thank you again for your detailed explanation. I believe I've learned a lot from this post. Thank you, Steve.

Re: I can't get the LINK macro working properly

PostPosted: Wed Aug 26, 2020 9:54 pm
by steve-myers
This is an example of the improper use of *+nn in an instruction stream; it is also a continuation of your topic of a few months ago about writing data proper data records to a USS file using a regular DCB and regular V format records.
         LA    0,L'FIELD
         LA    FIELD+L'
FIELD
         BCTR  15,0
         CLI   0(15),C' '
         BNE   *+12
         BCT   0,*-10
         LA    15,FIELD
         LA    14,FIELD
         SR    15,14
         EX    15,MVC
         LA    15,OUTPUT+1(15)
         LA    14,RDW
         SR    15,14
         STH   15,0(,14)
         ...
MVC      MVC   OUTPUT(*-*),0(14)
         ...
FIELD    DC    CL8'DATA'
RDW      DC    Y(*-*,0)
OUTPUT   DC    CL80' '
The code takes data in FIELD, finds the last non-blank, and copies the non-blanks to a V format record that starts at label RDW

Now I know you won't reply, but at least think about these questions.
  1. Are the *+12 and *-10 correct? I think they are, but I've been known to goof. How did I calculate the *+12 and *-10 addresses?
  2. Where does the *-10 branch to? Why do I want to branch there?
  3. Where does the *+12 branch to? Why do I want to branch there?
  4. What is the purpose of the LA following the BCT instruction? Hint: think FIELD is CL8' '
  5. What are the instructions following the EX instruction doing?
  6. Why is OUTPUT+1 used in the LA after the EX instruction?
I will answer one more possible query. Why do I use a Y type address constant in RDW DC Y(..? I use Y because it aligns to a halfword boundary; AL2 does not align to anything.

Re: I can't get the LINK macro working properly

PostPosted: Wed Aug 26, 2020 11:50 pm
by chong_zhou
steve-myers wrote:Now I know you won't reply, but at least think about these questions.
  1. Are the *+12 and *-10 correct? I think they are, but I've been known to goof. How did I calculate the *+12 and *-10 addresses?
  2. Where does the *-10 branch to? Why do I want to branch there?
  3. Where does the *+12 branch to? Why do I want to branch there?
  4. What is the purpose of the LA following the BCT instruction? Hint: think FIELD is CL8' '
  5. What are the instructions following the EX instruction doing?
  6. Why is OUTPUT+1 used in the LA after the EX instruction?
I will answer one more possible query. Why do I use a Y type address constant in RDW DC Y(..? I use Y because it aligns to a halfword boundary; AL2 does not align to anything.


Challenge accepted!

Let me try this quiz:

  1. Are the *+12 and *-10 correct? I think they are, but I've been known to goof. How did I calculate the *+12 and *-10 addresses?
    +12 and -10 are correct.
    +12 = L'BCT + 2*L'LA = 12. Both BCT and LA are RX-type 4-bytes instruction.
    -10 = L'BC + L'CLI + L'BCTR = 4 + 4 + 2 = 10. BC is RX-type, CLI is SI-type, they are 4-bytes and BCTR is RR-type which is 2-bytes.
  2. Where does the *-10 branch to? Why do I want to branch there?
    -10 branches to "BCTR 15,0", which is the beginning of the loop. That instruction moves the pointer register R15 back 1 char.
  3. Where does the *+12 branch to? Why do I want to branch there?
    +12 branches to "LA 14,FIELD". It is 1 instruction after the end of the loop. It loads the start of the FILED to R14. Since R15 points to the last non-whitespace char, R15-R14 gets the length of the content in FIELD (length-1, actually).
  4. What is the purpose of the LA following the BCT instruction? Hint: think FIELD is CL8' '
    Sorry, I really have no idea. R15 is supposed to be always pointing to a valid position inside FIELD provided it is not CL0. Even if FIELD is all whitespace and the loop stops by the BCT, R15 should still point to the first char in FIELD.
  5. What are the instructions following the EX instruction doing?
    LA-LA-SR calculates the VBREC's length which include the content of FIELD plus the 2 bytes record header.
    STH puts the length in the record header.
  6. Why is OUTPUT+1 used in the LA after the EX instruction?
After the EX, R15 holds the (length-1) of the content in FIELD. If we do "@OUTPUT + R15 - @RDW", we get the (record length-1), so we must plus 1 there. By the way, R15 must hold (length-1) due to MVC.

Regarding question 4... if FIELD has only 1 non-whitespace char, such as CL8'A', R15 will point to the 'A' after the loop, which will make R15 hold 0 as the length of content. However, if FIELD is CL8'', R15 will still point to the beginning of FIELD. This is a very small error and I don't even think it will bring any trouble. And neither do I think the "LA 15,FIELD" would make a difference, or, would it?...

Thanks, Steve, the quiz took that beginner (me) around an hour to do, and almost turned him on :D

Re: I can't get the LINK macro working properly

PostPosted: Thu Aug 27, 2020 1:06 am
by steve-myers
Your thoughts about the LA 15,FIELD after the BCT are quite reasonable. The code was sort of copied from another program, where FIELD was an 80 byte data area, and reg 3 has its address. As you deduced, its purpose is to handle an all blank data area - well, I hope the hint made that quite obvious. After I sent the little quiz in I realized reg 15 has the address of FIELD, so the LA is superfluous. In the program that was the template, there are blanks between the RDW and OUTPUT, which goes by a different label, so the LA is LA 15,RDW+5 so the output record has a valid carriage control character and the EX is not actually executed. When the EX instruction is executed, reg 15 has the number of bytes to copy - 1, which is the correct value for the length byte of an MVC instruction.

You didn't really answer question 6; since reg 15 has the number of bytes - 1 moved to OUTPUT, the purpose is to compute the address of the end of the record and OUTPUT+1 adjusts the reg 15 being 1 too low, then the SR 15,14 computes the actual record length which is stored in the RDW. As I said back in January, preparing a variable variable length record is not all that difficult!