But aren't both Example 1 & 2 still passing the address of literal =F'3' to the called routine, a literal that is only set at assembly time?   If there is a bug in the called routine that allows it to store a value back at that address at run time, it actually changes the value in the literal pool of the calling program, and the next time that call is executed the value may no longer be "3".  What's worse, if =F'3' is used in another totally different context in the calling program, it is probably using the same fullword "constant" in the literal pool and no longer getting a value of "3" there either.  The "CALL  MF=(E,...)" dynamically builds the list of parameter addresses, but it does not re-initialize any literal constants referenced by that list.  A literal like =F'3' is just shorthand for the-address-of a DC F'3' created out of line by the Assembler.  It implies there is no intent to store a different value there, but unless the program is running from read-only storage, the hardware doesn't prevent overwriting with a different value if you use the address of =F'3' as the target of a move or store.   A program that overwrites a literal at run time can be very difficult to debug, because what you see in the listings is misleading.

To be a functional "call by value" there needs to be a temporary fullword copy of the =F'3' constant made just before the call and that, or its address, passed on the call.  That temporary fullword can't be used in any other context in the calling program unless it's value is also set-before-use in that context as well.

That's not to say technique in Example 1 or 2 can't be used when you are certain that called subroutine does not return a value to that parameter, just don't be fooled by the =F'3' notation into thinking this represents a constant that can't be altered by the CALLed program and that this somehow becomes a call-by-value that prevents the called routine from overwriting the value.  Literals are created and initialized once at assembly time, not dynamically at execution time.

Example 3 would be a true "call by value", since the value "3" is rebuilt in storage for each call, and if that fullword is modified by the called routine it can have no side effects back in the calling routine.  That the CALL is passing an integer in a context where standard linkage conventions would expect a pointer to the integer is not an issue as long as the called routine expects that usage.

    Joel C Ewing

On 3/30/23 11:09, Frank Swarbrick wrote:
Perhaps the "weird way" could be documented as an appropriate way to pass 
arguments by value instead of the standard by reference.  Then it would no longer be 
weird!
________________________________
From: IBM Mainframe Discussion List <[email protected]> on behalf of Steve 
Smith <[email protected]>
Sent: Wednesday, March 29, 2023 9:16 PM
To: [email protected] <[email protected]>
Subject: Re: ASM call by value

Good job.  You could have a future as an assembler programmer, because you
pay attention to the details.

Your weird way is interesting because it is correct, but... it is not
idiomatic.  So it will freak out most assembler programmers.  That's often
not a good thing, but often is not always.

sas

On Wed, Mar 29, 2023 at 7:53 PM Frank Swarbrick <[email protected]>
wrote:

OK, the following three examples all seem to work.  I dare say you are
correct about example 1 being unexpected usage of the execute mode.  I only
came up with it my looking at an example that wasn’t working and seeing
that putting my value there directly made it work.  But it wasn’t meant to
be an example of good coding.

*
CALL1    CALL ,(,),MF=L
*
ISCICS#  CEEENTRY MAIN=NO
*
*        SEE IF WE'RE RUNNING UNDER CICS BY CALLING @@GETCb
*        WITH “VALUE” OF FULLWORD 3.
*
*        EXAMPLE 1 (MY WEIRD WAY):
          CALL  @@GETCB,MF=(E,=F'3')
*
*        EXAMPLE 2 (LOAD R1 DIRECTLY WITH ADDRESS OF AREA
*        CONTAINING 3, THEN JUST CALL):
          LA    1,=F'3'
          CALL  @@GETCB
*
*        EXAMPLE 3 (LOAD REGISTER (2) WITH VALUE,
*        THEN CALL WITH THAT REGISTER AS THE ARGUMENT:
          LHI   2,3
          CALL  @@GETCB,((2)),MF=(E,CALL1)
*
          CEETERM RC=(15)
*
PPA      CEEPPA
          CEEDSA ,
          CEECAA ,
          END   ISCICS#

I should note that I am not a systems programmer, or even an “assembler
programmer”.  I am a COBOL programmer who dabbles in assembler
occasionally.  So I am bound to get a lot of things wrong.

I think I’ll do with #2, since that generates the least amount of code and
is still fairly simple to read.

As for why I used X'0000000010000000200000003’ instead of F'1,2,3' in
another example, it’s because I didn’t know of the availability of using
“comma separated fullword” literals.


----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

--
Joel C. Ewing

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to