Hello once again,
further examination of the compile listing of COMMON showed:
the address passed to SQUARE ASSEMBLE as external ENTRY is in fact not the
starting address of the structure AREA1, but the address of a structure or table
descriptor.
The first address of the descriptor normally contains the address of the passed
parameter, but not in this case.
I tried to access the area by adding another L instruction:
L 6,=V(AREA1) REG6 POINTS TO EXTERNAL
L 6,0(6)
but then I got:
EXECUTION BEGINS...
P1 = 132624
P2 = -16777216
P1 = 132624
P2 = 132620
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
1310721 77
Ready; T=0.17/0.48 18:35:47
that is: now only 9 elements are computed, the 10th is missing.
The reason is, as you can see by looking at P2:
I didn't get the true starting address of the vector this way, but the so called
RVO (relative virtual origin) of the table, that is: the location of the element
with index zero, and that's why the loop doesn't reach the 10th element.
So you see:
as long as you don't know about the structure of the internal descriptions of
PL/1, it's best to compute the pointers at the PL/1 side and simply pass
pointers.
Works for me ...
Kind regards
Bernd
Am 28.03.2013 17:15, schrieb Bernd Oppolzer:
>
>
> Hello again,
>
> START
> EXECUTION BEGINS...
>
>
> P1 = 132624
> P2 = -16777216
> P1 = 132624
> P2 = -16777216
> 1 1
> 2 4
> 3 9
> 4 16
> 5 25
> 6 36
> 7 49
> 8 64
> 9 81
> 10 100
> Ready; T=0.17/0.49 18:11:22
>
>
> SQUARE2 looks like this:
>
> PRINT NOGEN
> SQUARE CSECT
> STM 14,12,12(13)
> BALR 11,0
> USING *,11
> L 2,0(1)
> L 6,0(2)
> * 10 NUMBERS
> USING AREA2,6 REG6 ALSO MADE THE BASE REGISTE
>
> no other changes, only the computation of reg 6 from the address list
> instead of the V constant
>
>
> and COMMON PLI was changed like this:
>
> P1 = ADDR (NUMBERS(1));
> P2 = NULL;
> CALL PUTADDR ('P1', P1); CALL PUTADDR ('P2', P2);
> CALL SQUARE (P1);
> CALL PUTADDR ('P1', P1); CALL PUTADDR ('P2', P2);
>
> the parameter P1 is passed to SQUARE (the starting address of
> the NUMBERS vector).
>
>
> Kind regards
>
> Bernd
>
>
>
>
>
> Am 28.03.2013 16:58, schrieb Bernd Oppolzer:
>>
>>
>> Hello,
>>
>> the problem is, that the ASSEMBLER subroutine does not get the starting address of
>> AREA1 by using the V constant, but some kind of structure or area description which
>> the PL/1 compiler puts in front of the actual area. I don't know the details; to examine this
>> further it might be necessary to look at the machine code generated by the PL/1 compiler.
>>
>> But what I did is:
>>
>> I passed the value that the ASSEMBLER subroutine got through the V constant back to
>> the PL/1 main program (through the reg 1 address list) and compared it to the actual
>> start of the vector NUMBERS in AREA1, and they are different (by 24 bytes) - which
>> fits well with the observed behaviour.
>>
>> Look at this:
>>
>> type square assemble
>>
>> ***********************************************************************
>> * SQUARE4 - ASSEMBLER SUBROUTINE CALLED FROM LIST FORTRAN TO SQUARE *
>> * A LIST OF 10 NUMBERS GENERATED BY LIST FORTRAN *
>> ***********************************************************************
>> *
>> PRINT NOGEN
>> SQUARE CSECT
>> STM 14,12,12(13)
>> BALR 11,0
>> USING *,11
>> L 2,0(1)
>> L 6,=V(AREA1) REG6 POINTS TO EXTERNAL
>> ST 6,0(2)
>> * 10 NUMBERS
>> USING AREA2,6 REG6 ALSO MADE THE BASE REGISTE
>> * REFERENCING NA
>> * REG6 IS THE WO
>> *
>> LA 9,10
>> BACK SR 4,4
>> L 5,NUM
>> MR 4,5
>> ST 5,PROD
>> LA 6,4(6)
>> BCT 9,BACK
>> *
>> LM 14,12,12(13)
>> BR 14
>> LTORG
>> AREA2 DSECT
>> NUM DS 10F
>> PROD DS 10F
>> END SQUARE
>>
>>
>> Ready; T=0.01/0.03 17:52:03
>>
>> type common pli
>>
>> COMMON: PROCEDURE OPTIONS(MAIN);
>> DCL 1 AREA1 STATIC EXT,
>> 2 NUMBERS(10) FIXED BIN(31),
>> 2 PRODUCT(10) FIXED BIN(31);
>> DCL I FIXED BIN(31);
>> DCL P1 PTR;
>> DCL P2 PTR;
>> DCL NULL BUILTIN;
>> DO I = 1 TO 10;
>> NUMBERS(I) = I;
>> PRODUCT(I) = 77;
>> END;
>> P1 = ADDR (NUMBERS(1));
>> P2 = NULL;
>> CALL PUTADDR ('P1', P1); CALL PUTADDR ('P2', P2);
>> CALL SQUARE (P2);
>> CALL PUTADDR ('P1', P1); CALL PUTADDR ('P2', P2);
>> DO I = 1 TO 10;
>> PUT SKIP LIST (NUMBERS(I), PRODUCT(I));
>> END;
>>
>> PUTADDR: PROC (CH, P);
>> DCL CH CHAR (*);
>> DCL P PTR;
>> DCL BP BIN FIXED (31) BASED (PP);
>> DCL PP PTR;
>> PP = ADDR (P);
>> PUT SKIP LIST (CH || ' = ' || BP);
>> END PUTADDR;
>>
>> END COMMON;
>>
>> Ready; T=0.01/0.02 17:53:28
>>
>> tt
>> GLOBAL TXTLIB PLILIB
>> EXEC PLICOMP COMMON
>> FILEDEF * CLEAR
>> PLI COMMON ( LIST XREF
>> COMPILER DIAGNOSTICS.
>>
>> WARNINGS.
>> IEM0227I NO FILE/STRING OPTION SPECIFIED IN ONE OR MORE GET/PUT STA
>> TEMENTS. SYSIN/SYSPRINT HAS BEEN
>> ASSUMED IN EACH CASE.
>>
>> END OF DIAGNOSTICS.
>> +++ R(00004) +++
>> FILEDEF * CLEAR
>> ASSEMBLE SQUARE
>>
>> ASSEMBLER (XF) DONE
>> NO STATEMENTS FLAGGED IN THIS ASSEMBLY
>> LOAD COMMON SQUARE ( CLEAR
>> FILEDEF SYSPRINT TERM
>> START
>> EXECUTION BEGINS...
>>
>>
>> P1 = 132624
>> P2 = -16777216
>> P1 = 132624
>> P2 = 132600
>> 1 1
>> 2 4
>> 3 9
>> 4 16
>> 408195216 77
>> 16 77
>> 1310721 77
>> 418806416 77
>> 16 77
>> 1310721 77
>> Ready; T=0.17/0.48 17:54:49
>>
>>
>> Please remember: PL/1 is different from FORTRAN, it does many crazy things
>> when passing parameters, and you have always to take this into account,
>> when accessing PL/1 areas from ASSEMBLER language.
>>
>> Next step: I will change SQUARE and the PL/1 programm to work on the
>> true starting address passed by reg1, and I think, it will work this way.
>>
>> Kind regards
>>
>> Bernd
>>
>>
>>
>> Am 28.03.2013 05:31, schrieb G.M.:
>>>
>>>
>>> This is nice. A FORTRAN program generates a list of 10 numbers
>>> and then calls an Assembler subroutine which will square each of the 10 numbers.
>>> A DSECT is used as a template for the common area,
>>> so no dealing with Reg 1, or using registers for indirect addressing;
>>> just simple variables NUM, and PROD.
>>> Ready; T=0.01/0.01 22:10:35
>>>
>>> type list fortran
>>>
>>> INTEGER NUM(10), PROD(10)
>>> COMMON /AREA1/NUM,PROD
>>> DO 10 I = 1,10
>>> NUM(I) = I
>>> 10 CONTINUE
>>> CALL SQUARE
>>> DO 20 I=1,10
>>> WRITE(6,100) NUM(I),PROD(I)
>>> 20 CONTINUE
>>> 100 FORMAT(2X,I2,3X,I3)
>>> END
>>>
>>> Ready; T=0.01/0.02 22:11:01
>>>
>>> type square4 assemble
>>>
>>> ***********************************************************************
>>> * SQUARE4 - ASSEMBLER SUBROUTINE CALLED FROM LIST FORTRAN TO SQUARE *
>>> * A LIST OF 10 NUMBERS GENERATED BY LIST FORTRAN *
>>> ***********************************************************************
>>> *
>>> PRINT NOGEN
>>> SQUARE CSECT
>>> STM 14,12,12(13)
>>> BALR 11,0
>>> USING *,11
>>> L 6,=V(AREA1) REG6 POINTS TO EXTERNAL AREA HOLDING THE
>>> * 10 NUMBERS.
>>> USING AREA2,6 REG6 ALSO MADE THE BASE REGISTER WHEN
>>> * REFERENCING NAMES IN THE DUMMY SECTION
>>> * REG6 IS THE WORKHORSE BEHIND THE SCENE
>>> *
>>> L 9,=F'10'
>>> BACK SR 4,4
>>> L 5,NUM
>>> MR 4,5
>>> ST 5,PROD
>>> A 6,=F'4'
>>> BCT 9,BACK
>>> *
>>> LM 14,12,12(13)
>>> BR 14
>>> LTORG
>>> AREA2 DSECT
>>> NUM DS 10F
>>> PROD DS 10F
>>> END SQUARE
>>>
>>> Ready; T=0.02/0.08 22:12:11
>>>
>>> fortran list
>>> COMPILING: LIST
>>>
>>> Ready; T=0.03/0.08 22:12:32
>>>
>>> assemble square4
>>>
>>> ASSEMBLER (XF) DONE
>>> NO STATEMENTS FLAGGED IN THIS ASSEMBLY
>>> Ready; T=0.20/0.30 22:12:58
>>>
>>> load list square4
>>> Ready; T=0.16/0.19 22:13:33
>>>
>>> filedef 6 term
>>> Ready; T=0.01/0.01 22:13:48
>>>
>>> start
>>> DMSLIO740I Execution begins...
>>> 1 1
>>> 2 4
>>> 3 9
>>> 4 16
>>> 5 25
>>> 6 36
>>> 7 49
>>> 8 64
>>> 9 81
>>> 10 100
>>> Ready; T=0.01/0.02 22:13:54
>>>
>>> COOL! Program worked.
>>>
>>> Now look what happens when a PL/I program generates the same numbers and calls
>>> the same Assembler subroutine:
>>>
>>> type common pli
>>> COMMON: PROCEDURE OPTIONS(MAIN);
>>> DCL 1 AREA1 STATIC EXT,
>>> 2 NUMBERS(10) FIXED BIN(31),
>>> 2 PRODUCT(10) FIXED BIN(31);
>>> DCL I FIXED BIN(31);
>>> DO I = 1 TO 10;
>>> NUMBERS(I) = I;
>>> END;
>>> CALL SQUARE;
>>> DO I = 1 TO 10;
>>> PUT SKIP EDIT(NUMBERS(I), PRODUCT(I)) (COL(2), F(3), X(2), F(3));
>>> END;
>>> END COMMON;
>>>
>>> Ready; T=0.01/0.02 22:14:54
>>>
>>> pli common
>>> COMPILER DIAGNOSTICS.
>>>
>>> WARNINGS.
>>> IEM0227I NO FILE/STRING OPTION SPECIFIED IN ONE OR MORE GET/PUT ST
>>> ASSUMED IN EACH CASE.
>>>
>>> END OF DIAGNOSTICS.
>>> Ready(00004); T=0.31/0.37 22:15:07
>>>
>>> filedef * clear
>>> Ready; T=0.01/0.01 22:15:18
>>>
>>> load common square4
>>> Ready; T=0.08/0.09 22:15:34
>>>
>>> filedef sysprint term
>>> Ready; T=0.01/0.01 22:15:45
>>> start
>>> DMSLIO740I Execution begins...
>>>
>>>
>>> 1 1
>>> 2 4
>>> 3 9
>>> 4 16
>>> 592 0
>>> 16 0
>>> 721 0
>>> 992 0
>>> 16 0
>>> 721 0
>>> Ready; T=0.23/0.30 22:15:52
>>>
>>> Everything was going fine until it got to the fifth number where it blew up. What screwed up the list?
>>>
>>
>
|