The Importance of Terminology's Quality

Robert Maas, jaycx2.3.calrobert at spamgourmet.com.remove
Tue Aug 12 21:28:33 CEST 2008


John W Kennedy <jwke... at attglobal.net> 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.



More information about the Python-list mailing list