Oppolzer - Informatik / Blog


Blog-Hauptseite      Neuester Artikel      Älterer Artikel      Neuerer Artikel      Älterer gleiche Kategorie      Neuerer gleiche Kategorie

Hercules - Aufruf eines externen Unterprogramms in PL/1

Subject:

Re: [H390-VM] Re: PL/I Main Program calling an External Subroutine

From:

Bernd Oppolzer <bernd.oppolzer@T-ONLINE.DE>

Reply-To:

Date:

2013.03.28 17:15:00


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?
>>
>

Blog-Hauptseite      Neuester Artikel      Älterer Artikel      Neuerer Artikel      Älterer gleiche Kategorie      Neuerer gleiche Kategorie