21

As described in these answers, the jump table offsets to functions contained in an AmigaOS library are always negative values. The reason for this is not intuitive to me, but I suspect Carl Sassenrath had some good reason(s) for doing it this way (as opposed to just using positive offsets).

What functionality or convenience is gained by having these offsets be negative values from the base address?

28

TL;DR:

What functionality or convenience is gained by having these offsets be negative values from the base address?

It provided easy access to two lists that can be extended independently in future versions with a single pointer.


The Long Read:

A single pointer can only point a single memory location (yes, sound obvious, but stay with me). So at first sight there can be only a single data structure that pointer points to. In case of Amiga libraries that is the Library structure describing the library and its usage.

But to access functions there needs to be a second data structure holding entry points (either directly or as addresses (*1)). The two conventional methods to add something like entry points/jump tables are

  1. Locate all entry points after that library structure and use offsets from there on.
  2. Add a pointer for an entry point table to the library structure and make all offsets relative to that address.

Solution 1 would make any extension of the structure rather hard, as it would change offsets of functions each time the OS changes/extends the header. Not a good idea for an upward compatible library system.

Solution 2 is one most OSes (including Windows) use. It avoids the pitfalls about version dependence. On the down side, it comes with an additional instruction (not really a big issue) and the usage of two pointers. one to identify the library and one to handle the entry point table. This might not seem much, and as mentioned, many OSes did go that way.

But not Amiga-OS. They went for a third way: using the one-dimensional nature of address space in both directions. Consider the memory as a (not really) endless sequence of memory cells that can be traversed not only upwards but in both directions, enabling the addressing of two structures with a single pointer - as long as they lie back to back.

To see the effect it's helpful to take a look at a nice picture RichF already presented in an answer to the mentioned question:

Figure 1.1: Amiga Library Structure and Jump Table

Using the one dimensional nature in both directions offers several advantages:

  • Both structures can grow with new versions without intruding on either
    • New entry points can be added with new library versions
    • The library structure can be extended for newer OS versions
  • No need to calculate a second pointer for the jump table
  • No need to handle two pointers (library and entry table)
  • Only one pointer for everything about that library

The last point can't be stressed enough.

  • One pointer is all any user for that library needs.
  • No programmer has a chance of using the wrong one
  • It makes a unique identifier for the loaded library

Of course this only works on an ISA allowing negative offsets - handy that the 68k does exactly that :) Speaking of 68k:

  • There is no indirect jump with a target address in memory
  • Register indirect plus (negative) offset JSR is with 18 clock as fast as an absolute JSR.

Bottom line:

  • While the advantages may seem small, they help a lot when it comes to system design in terms of simplicity, usability and upward compatibility.
  • And all of that without any disadvantage (on 68k).

*1 - Here it's important to keep in mind that the Amiga was a rather slow machine - incredibly slow by today's standards. Every cycle counts. At the same time Amiga-OS tried to be as clean and well-defined as possible.

11
  • 9
    Someone will say it, though I'm not sure it's completely relevant: most implementations of malloc do the same one-pointer-to-two-things dance. On the positive side of the pointer is the buffer you actually asked for, on the negative is whatever information free will need to do its bookkeeping. Though, again, I guess it's only very broadly related — in the sense of allowing two things of decoupled size to be referenced by a single pointer with no skipping-a-bit burden on either kind of consumer. It's completely irrelevant as concerns the version dependence stuff.
    – Tommy
    Feb 23 at 22:17
  • 4
    @Tommy Oh, of course. I would never say this isn't used in other places as well. In fact, classic MS-DOS memory management is kind of similar to your description, just with the little drawback that the 8086 can/does not use negative offset. Something the 68k can do (Added a few lines about that). So only CPUs that allow regular use of a negative offset may really use two structures with a single pointer. It of course opens as well a whole sack of philosophical discussions.
    – Raffzahn
    Feb 23 at 22:26
  • 1
    They used the same trick again when retrofitting old gadget structures into an object oriented design in Amiga OS 2.0. The old structure started at offset zero, looking like before (except for an additional flag), class information and list node structure were placed at negative offsets.
    – Holger
    Feb 24 at 10:38
  • 2
    @nsandersen: True. They'd typically be allocated using the AmigaOS AllocMem routine (called internally by OpenLibrary), which stores no metadata for allocated blocks. (The AmigaOS allocator only keeps track of unallocated memory, and relies on the caller to keep track of the size of the allocated memory chunk and to pass it to FreeMem.) But I think Tommy's comment was meant as an analogy between two different uses of the negative offset trick, not as an implication that both would be used together. Feb 24 at 16:10
  • 1
    8086 can/does not use negative offset Huh? It's still base-segment relative, but you can certainly add a negative index in any addressing mode that takes index literal operands, unless I'm just grossly misremembering from the last time I wrote x86 by hand... Feb 24 at 21:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.