The function @PRINTF4 is also shown in the IBM example:
|/* this example demonstrates C/Assembler ILC */ /* part 3 of 3 (other
files are CCNGCA2, CCNGCA4) */
/*******************************************************\ * This routine
is an interface between assembler code * * and the C/C++ library
function printf(). * * OS linkage will not tolerate C-style variable
length * * parameter lists, so this routine is specific to a * *
formatting string and a single 4-byte substitution * * parameter. It's
specified as an int here. * * This object wil be named @PRINTF4. *
/*******************************************************/ #pragma
linkage(_printf4,OS) /*function will be called from assembler*/ #include
<stdio.h> #pragma map(_printf4,“@PRINTF4”) int _printf4(char *str,int i)
{ return printf(str,i); /* call runtime library function */ }|
what you see here is the special behaviour because of the #pragma
linkage(...,OS) ..
this is NOT the standard behaviour of C.
The parameter int i is passed BY ADDR in this case ...
with the #pragma you can override nomal C "by value" behaviour (which
means,
that the function cannot be called by "normal" C, which doesn't know about
this #pragma).
We never allowed the use of #pragma linkage at our site ... that's why
we had to
build the glue functions to support the 3rd party package in the 1990s.
(Or, IIRC,
we asked the supplier of the software to do this for money).
Kind regards
Bernd
Am 31.03.2023 um 01:42 schrieb Bernd Oppolzer:
See answers below
Am 31.03.2023 um 01:23 schrieb Paul Gilmartin:
On Thu, 30 Mar 2023 23:39:30 +0200, Bernd Oppolzer wrote:
"call by value" in my understanding means, that values are passed, not
addressed.
With the mainframe (or z/OS and CMS) linkage convention, this means,
that values
and not addresses are in the reg1 parameter list.
What happens if there are more value parameters than the total
capacity of registers?
(But do I misunderstand? Is the "reg1 parameter list" not actual
registers but the
storage addressed by GR1 in the CALL macrlo? If so, it's no
practical limit.)
reg1 parameter list is the address list which register 1 points to.
So there is no practical limit on the size of the parameter list.
Of course, it is impractical to pass large structures or arrays by value,
but that's what every C tutorial will tell you ...
see above. Because the values entered into the reg1 list "by value" can
be negative integers
(or other types, which need more that 4 bytes), the VL convention
cannot
be used by C callers
Hmmm. In
<https://www.ibm.com/docs/en/zos/2.5.0?topic=programs-calling-c-code-from-assembler-c-example>
I see:
EDCPRLG
LA 1,ADDR_BLK parameter address block in r1
L 15,=V(@PRINTF4) address of routine
BALR 14,15 call @PRINTF4
EDCEPIL
ADDR_BLK DC A(FMTSTR) parameter address block with..
DC A(X'80000000'+INTVAL) ..high bit on the last address
* ...
INTVAL DC F'222' The integer value displayed
*
Isn't the "X'80000000'" setting the VL bit?
(I note that's a CD not an EQU. But the reg1 PL contains an address
not a value.)
Again, either the caller or the called routine could be able
to convert addresses to values.
This @PRINTF4 cannot be the same as normal PRINTF;
it must be a glue function or similar to allow an ASSEMBLER function
to call normal PRINTF.
(only guessing, because the FMTSTR is not shown here).
If normal PRINTF is called, the sequence should look like this:
LA 1,ADDR_BLK parameter address block in r1
L 15,=V(PRINTF) address of routine
BALR 14,15 call normal PRINTF
...
ADDR_BLK DC A(FMTSTR) parameter address block with..
DC F(222)
FMTSTR DC C'output of integer %d using printf'
DC X'00'
As you can see, because the integer value can be positive or negative,
there is no way to mark the last parameter with the leftmost bit.
Old story from my old customer:
sometime we had to introduce 3rd party software (written in C) which
had to be
called from PL/1 routines. PL/1 at that time only had call by
reference, but the
routines of the 3rd party software used call by value in their
interfaces or APIs.
We had to provide so-called "glue functions" for every function of the
3rd party
software, that had a call by value parameter ... the call by value
parameter
was a reference-parameter in "our" interface, callable by PL/1, and then
the glue function called the 3rd party function, using the by-value
interface.
This was in the 1990s ... today BYVALUE is supported by native PL/1.
Maybe the same is going on here with that @PRINTF4 interface ??
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN