Hello again,
after looking again at the prior results
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
and thinking a little bit about the things I know about PL/1 descriptors etc.,
I realized, that the ASSEMBLER subprogram in fact squared the data in the
descriptors and wrote the results to the vector NUMBERS, that is, the corrupted
data in the left column (index 5 to 10) are the squares of the data in the
descriptors.
The program, instead of reading the vector NUMBERS, indices 1 to 10, and writing
to PRODUCTS, indices 1 to 10, read the descriptors and the NUMBERS 1 to 4, and
wrote to NUMBERS 5 to 10 and to PRODUCTS 1 to 4, and left the rest unchanged.
So we are able to tell what was in the descriptors by looking at the squares in
NUMBERS 5 to 10.
The descriptors are two table descriptors, consisting of 3 words. The first word
contains the address of the RVO (relative virtual origin, as already explained).
The second word contains the length of one element, that is: 4. The third word
contains the upper and lower limit of the vector indices, that is, 10 and 1. If
you square the value X'000A0001', you get the decimal result 1310721.
The idea is, that all those values be passed to the subroutine, so that the
subroutine can be variable with respect to those array boundaries etc. - this is
quite different from FORTRAN. But if you do this in ASSEMBLER, you have to take
all this bells and whistles into account, and you have to know about the PL/1
descriptor logic.
There must be old books "PL/1 execution logic", where all this things are
documented. I recently talked with Peter Elderon, who is responsible at IBM for
PL/1, and these things where missing in the current documentation, but they were
added soon after that, AFAIK. So those things are still important today, at
least for large shops like ours, which use PL/1 heavily.
Kind regards
Bernd
Am 28.03.2013 17:39, schrieb Bernd Oppolzer:
> 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
>
>
|