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