John W Kennedy <[EMAIL PROTECTED]> wrote: JWK> Into the 60s, indeed, there were still machines being made JWK> that had no instruction comparable to the mainframe BASx/BALx JWK> family, or to Intel's CALL. You had to do a subprogram call by JWK> first overwriting the last instruction of what you were JWK> calling with a branch instruction that would return back to JWK> you.
That's not true, that you needed to do that, that there was no other way available. The subroutine linkage I invented for S.P.S. (Symbolic Programming System, i.e. IBM 1620 assembly language) was to reserve a 5-digit space immediately before the subroutine entry point for storing the return address. So the caller needed to know only one address, the entry point, and do both store-return-address and jump relative to that address, rather than needing to know both the entry point and the last-instruction-JUMP-needs-patch address as independent items of information. So calling a subroutine was two instructions (pseudo-code here): literal[nextAdrOfSelf} -> memory[SubrEntryPoint-1] jump to SubrEntryPoint and returning from a subroutine was two instructios: copy memory[SubrEntryPoint-1] -> memory[here + 11] jump to 00000 ;These zeroes replaced by return address just above Of course if you needed to pass parameters and/or return value, that was handled separately, perhaps by reserving additional storage just before the return address. Of course this methodology didn't support recursion. So my method required one extra instruction per return point, but allowed multiple return points from a single subroutine, and allowed "encapsulation" of the relation between entry point and return point. Note: On IBM 1620, instructions and forward-sweeping data records were addressed by their *first* digit, whereas arithmetic fields were addressed by their *last* digit, the low-order position, to support natural add-and-carry operations. Storage was decimal digits, with two extra bits, flag to indicate negative value (if in low-order position) or high-order-end (if in any other position), and parity. Values larger than nine were reserved for special purposes, such as RECORD MARK used to terminate right-sweep data records. Because of that, the low-order position of the return address and the first digit of the machine instruction at the subroutine entry point differed by only machine address, hence the SubrEntryPoint-1 instead of SubrEntryPoint-5 you would otherwise expect. Hmm, I suppose if I had thought it out more at the time, I might have done it slightly differently: Entry point like this: jump 00000 ;Patched by caller to contain return address Entry: ...(regular code)... ... Each return point like this: jump Entry-12 I wonder if anybody ever implemented a stack on the IBM 1620? Probably not, because it would take a lot more machine instructions to push and pop, and if you weren't writing anything recursive then extra work for no extra benefit except saving a few digits of memory if your maximum stack depth is less than the total number of subroutines you have loaded, except the extra instructions more than kill off the storage savings. Hmm, I suppose you could have a auxilary function that serves as trampoline for stack-based call and return. To call, you move your own return address and address of subroutine to fixed locations in low memory then jump to the call trampoline, which pushes the return address onto the stack and jumps at entry address. To return, you just jump to the return trampoline, which pops the return address off the stack and jumps at it. The trampoline, occuping memory only *once*, could afford to have code to safely check for stack over/under flow. -- http://mail.python.org/mailman/listinfo/python-list