Skip to content
Techniques & Technology

Position-Independent Code

Code that runs anywhere

Code that runs correctly wherever it is loaded, because every reference is relative to the program counter. The 6809's architects made it their highest-priority design goal (BYTE, 1979), Motorola's manual made it a rule, OS-9 made it a requirement; 6502 programmers managed it by effort.

trs-80-color-computerdragon-32cross-platformassembly6809addressingrelocation

Position-independent code runs correctly wherever it is loaded, because every reference it makes is relative to the program counter rather than to a fixed address. The Motorola 6809 is the 8-bit processor built around the idea: its architects named it their highest-priority goal in 1979, and Motorola’s programming manual made it a rule. Programmers had managed it on the 6502 by effort before that; OS-9 made it a requirement afterwards.

Fast facts

  • Definition (Motorola, 1981): “A program is said to be ‘position-independent’ if it will run correctly when the same machine code is positioned arbitrarily in memory.”
  • The rule: “NEVER USE ABSOLUTE ADDRESSING.”
  • The cost: “usually 5 to 10% slower than normal code” (Motorola, 1981).
  • 6809 mechanism: program-counter relative addressing on every memory-referencing instruction, plus LEA to take the address of a table.
  • Why it was wanted: ROMs that could be sold into “arbitrary target systems” (Ritter and Boney, BYTE, February 1979).

The problem the 6809 was designed for

Terry Ritter and Joel Boney, the 6809’s architects at Motorola, set out the case in BYTE in January 1979, before the chip shipped. The trouble with second-generation processors, they wrote, was ROM:

It is very difficult to use a read only memory in any other context than that for which it was originally developed. It is hard to use the same read only memory on systems built by different vendors. Simply having different input and output (IO) or using a different memory location is usually enough to make the read only memory product useless.

Their list of what was needed began “1. Position independent code”, followed by temporary variables on the stack, I/O through pointers on the stack, and absolute indirect operations for system branch tables. “Implementation of position independent code was one of the highest priority design goals. The 6800 had limited position independent code capabilities for small programs, but we felt the 6809 must make this type of code so easy to write that most programmers would make all their programs position independent.”

The February instalment put the commercial argument in one paragraph: “Only read only memories which may be used in arbitrary target systems are economically viable in the context of mass production. And only these read only memories can result in low cost firmware for us all.”

How the 6809 does it

The mechanism, in the architects’ words: “Program relative addressing uses the program counter much as indexing uses one of the indexable registers. This allows all instructions that reference memory to reference data relative to the current program counter (which is inherently position independent).” Branches gained a 16-bit long-relative form. The remaining gap was taking the address of a table inside a ROM — “generally a tedious process even in computers that claim to support position independent code because the register that points to the table must eventually contain an absolute address” — which the LEA instruction closes “with one instruction”.

Motorola’s 1981 programming manual turned this into practice. Position-independent programs “never use absolute (extended or direct) addressing”; the assembler computes the distance from the instruction to the symbol, and “during execution, the processor adds the value of the run time PC to the distance to get a position-independent absolute address”. The manual’s example points X at a message with LEAX MSG1,PCR. Its one concession is I/O: “some absolute locations are usually required, particularly for I/O”, so a small setup routine pushes the device addresses onto the stack and every other module reaches the hardware through that pointer. The manual prices the whole discipline at “usually 5 to 10% slower than normal code”.

Where it was required

Microware’s OS-9 for the 6809 — sold by Radio Shack for the Color Computer and later shipped on the Dragon — loaded modules wherever memory was free, so its code had to be position-independent by rule. Color Micro Journal’s October 1983 review of the package listed “Position Independent” among the terms a new user had to learn, and noted that the Technical Information Manual devoted a chapter to “how to write Position-Independent Code, Addressing Variables and Data Structures (which are almost NEVER at a fixed Memory Address location)”.

On processors without PC-relative data access

The 6502 has relative branches only, and no way to load data relative to the program counter; the Z80 is the same. Position-independent code was still written for them, at a cost in effort. MICRO published a 6502 file-handling subroutine for the AIM 65 in July 1980 that was “completely position-independent and ROMable”: “you can put it anywhere in memory that you like. You will not have to change a single byte of code.” Ritter and Boney’s own assessment of the 6800 — “limited position independent code capabilities for small programs” — describes the situation on these processors well: possible for a small routine, impractical for a large program.

The 68000 sits in between. Its programmer’s reference manual classes the program-counter-relative modes as data, memory and control addressing but not “alterable”: code can read a table through the PC but cannot write through it. Motorola’s manual is explicit that “data items in the instruction stream can be accessed with the program counter relative addressing modes” and that these count as program references — the ROM-table case the 6809’s LEA was built for.

See also

Not yet fact-checked. This entry was drafted by an AI and nobody has verified it. The dates, figures and technical details may be wrong. Use it to find your bearings, then confirm anything that matters against a primary source.