Linkage (calling functions with arguments and returning with values) on the 7090/94 depended on the 'TSX' (Transfer and Set Index) instruction.
'TSX' placed the 2's complement of the address of the instruction itself into a specified index register and then transferred to the instruction specified by the 'Y' address. Once inside the called subroutine, incoming variables -- pointers to which were usually strung after the 'TSX', could be easily accessed via the index register and indirect addressing. Returned results could be placed into similarly strung out variables. The return from the called subroutine was easily accomplished with a 'TRA' (Transfer) instruction that specified an offset and the index register.
The 7090 SHARE convention was to use XR4 for subroutine linkage although there was no technical requirement to follow the suggestion.
'TSX' used the 2's complement of the return address so that index register usage (which always subtracts the offset) would always correctly function.
The pointers to the variables that were strung out after the 'TSX' were created with the 'PZE' FAP Assembler directive which would put a zero operation code in the location along with the address of the variable itself.
The following simple example, that calculates X ** 2 + Y and places the result into ANS, illustrates typical subroutine linkage:
Main Procedure Subroutine
TSX SUBRT, 4 (Call Subroutine) SUBRT LDQ* 1, 4 (Get X Value by Indirect through Index & Offset)
PZE X (Pointer to X) FMP* 1, 4 (Multiply by X to Get X ** 2 by Same Route)
PZE Y (Pointer to Y) FAD* 2, 4 (Add in Y to Get X ** 2 + Y with Different Offset)
ANS BSS 1 (Will Hold Result) STO 3, 4 (Store Result in ANS through Index & Offset)
TRA 4, 4 (Return through Index & Offset)
RENTRY ... (Press On)
The steps are as follows:
In the above example, in the main procedure, variable ANS could have been placed elsewhere and replaced, in the calling sequence, with a 'PZE ANS' pointer to the actual location. For this change to work, it would have been necessary to change the 'STO 3, 4', in the subroutine, to 'STO* 3, 4' for the linkage to remain correct. Similarly, the X and Y variables could have been placed in the calling sequence in which case the indirects on the 'LDQ', 'FMP', and 'FAD' would have disappeared.
- The 'TSX' places the address of the call in XR4 (actually the 2's complement) and transfers to SUBRT.
- Inside SUBRT, the 'LDQ*' uses XR4 as a pointer to the pointer in the main procedure to X. The pointer in the main procedure is created by the 'PZE X'. Indirection through the pointer to the pointer retrieves the value of X and places it into the MQ register for the multiply.
- The 'FMP*' fetches the value of X again and multiplies to get X ** 2.
- The 'FAD*' fetches the value of Y (the pointer to Y in the main procedure is offset from the address in XR4 by 2 words) and multiplies to get X ** 2 + Y.
- The 'STO' stores the result in ANS. Indirection is not needed as ANS, in the main procedure, is not a pointer but is rather the actual variable. The location of ANS is offset from the address in XR4 by 3 words.
- The 'TRA' returns back to the main procedure by transferring to the address offset by 4 from the address contained in XR4 (labeled RENTRY).
If it was necessary to save the contents of the linkage index register (for example, calling a more deeply nested routine), the most efficient way was to use the 'SCA' (Store Complement of Index in Address) and 'AXT' (Address to Index True) instructions as follows:
The above code fragment, of course, modifies at run-time the contents of the instruction at RSTOR to fill in the saved contents of XR4.
SCA RSTOR, 4 (Store Index Register Contents in Address Portion of Return Instruction)
. (Code that Modifies XR4...)
RSTOR AXT *, 4 (When Executed, will have Saved XR Contents in Y Field -> XR4)
TRA 1, 4 (Return assuming No Arguments etc)
http://www.frobenius.com/Linkage.htm -- Last Revision: 23 August 2001
Copyright © 1996 - 2017 Jack Harper (unless otherwise noted)