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 16:58:00


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