# 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: From: Bernd Oppolzer Reply-To: Date: 2013.03.28 18:33:00

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