GARTHWILSON wrote:
> It might be used, for example, in writing relocatable code, but this is not done much with the 6502. The 65816 has more capabilities in this area.
No it doesn't.
It has the exact same set of (basic) primitives available for manipulating the PC as the 6502 did. The only new additions are support for indirect JSRs and some new branch modes.
Other than that, the 65816 is as static as the 6502.
That being said, relocatable code and position-independent code (PIC) are generally considered to be separate things in the field of computer science, and it's important to distinguish between them (unless you explicitly define what you mean).
Relocatable code is basically static code emitted by an assembler or linker, but with additional "meta-data" (as it's called) informing the code loader where things need to be relocated. So, if you have the following instructions:
Code:
LDA RegisterX
JSR FunctionY
The resulting opcodes will probably be emitted like this:
Code:
AF 00 00 00 : LDA RegisterX
20 00 00 : JSR FunctionY
Note that, if left unmodified, the CPU would see these instructions as targetting location 0 in all cases. To prevent this, the loader needs to know three things for each relocation "fixup":
1. Where in the loaded image do I relocate,
2. What value do I
add to what's already there, and,
3. How big is the field I'm modifying?
Executable formats like this are said to be "relocatable file formats," because relocation occurs at
load-time. Such a relocation table might look like this (assuming the above code started at offset zero):
Code:
01 00 ; At offset $0001, there is...
01 00 ; ... a 24-bit absolute address, which ...
xx yy ; ... references symbol number $YYXX (in this case, RegisterX).
05 00 ; At offset $0005, there is...
02 00 ; ... a 16-bit absolute address, which ...
ww zz ; ... references symbol number ZZWW. (in this case, FunctionY).
Position-independent code, however, is software that is written expressly to be dynamically repositioned
at run-time. This requires the software to constantly determine where things are because it doesn't know whether or not it's been moved. Therefore, you'll see instruction sequences such as this quite often:
Code:
JSR t0
t0:
STY tmpY ; assume some constant zero/direct page location
PLY
LDA fixed-offset,Y
LDY tmpY
It's ugly, it's slow, and on the 6502, it's overwhelmingly more efficient to NOT do this. It's actually better to keep a table of fix-ups for the binary in the binary itself, and when dynamic relocation is necessary (the rules for adding offsets to what's there are going to be different of course), it's done at the time of relocation, rather than run-time.
Note that CPUs with lots of registers can get around this, since they usually have at least the following addressing modes:
Code:
offset[regA,regB]
[regA,regB]
where regA is used as some pointer relative to regB (which I'll define to be the "base" since it's assigned regB), which in turn is further offset by the constant, if given. Such CPUs can usually do this math in a single clock, maybe two at most (now-a-days at least).
For example, in AmigaOS Classic (68000-based environment), register A6 is used as the shared library base pointer, from which all library-related data can be accessed (including system information).
--
Samuel A. Falvo II