Linker Resources

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
beethead
Posts: 9
Joined: 03 Dec 2019

Linker Resources

Post by beethead »

Most 65xx assemblers tend to be of the traditional multi pass variety writing a binary file in the last pass and then there are the handfull of linker types. Everyone has their own preference and my past experiences has been with the multi pass type but more recently I've been looking at the linker type. What online resources are there for someone wishing to incorporate a linker/linking step into their own assembler? Object file formats, relocation tables, etc...

I've built my 6502/65816 cross assembler similar to Table Assembler, pattern matching to determine opcodes and addressing modes.
Last edited by beethead on Wed Dec 04, 2019 5:04 pm, edited 1 time in total.
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Linker Resources

Post by cjs »

I'm quite interested in this, too, though I don't have much in the way of resources to offer. I can mention some 6502 or multiplatform assemblers that include a linker; studying their object file formats might be helpful.

Multiplatform cross-assemblers:
  • ASxxxx. The object file formats for both v4 and v3 are documented here.
  • The Amsterdam Compiler Kit. Includes C/Pascal/Modula-2/Occam compilers for some CPUs, but many have just an assembler. I don't know much about it beyond that.
  • The AS Macro Assembler has started developing support for a linker. The code is in alink.c, and it compiles that to a running program, but there's no documentation yet.
6502- and 65816-specific cross-assemblers:
  • cc65, of course. I've hacked on the libs but don't know much about the object file format. It does include a cool feature that lets you automatically embed information about constructors, destructors and other similar objects in the object files so that initialization code can use the sum of these after the link. That's a useful feature that you might want to keep in mind.
  • Dev65 uses an XML format for the linker files; see BitWise's post below for more on that.
Native-platform assemblers:
  • Commodore's DevPak editor/assembler for the C-128.
If anybody posting further down the thread wants their information incorporated into this list (since it's the second post), just mention that and I'll do it.
Last edited by cjs on Wed Dec 04, 2019 10:59 pm, edited 2 times in total.
Curt J. Sampson - github.com/0cjs
User avatar
BitWise
In Memoriam
Posts: 996
Joined: 02 Mar 2004
Location: Berkshire, UK
Contact:

Re: Linker Resources

Post by BitWise »

Dev65 uses XML as its object code format which made it easy to debug. I was going to pass the XML through a ZIP compression before writing to disk but disks got so big I can't see the point any more.

Normally its not generated with any spaces but this is what it looks like when pretty printed.

Code: Select all

<?xml version="1.0"?>
<module target="65XX" endian="little" byteSize="8" name="test.obj">
	<section name=".code" size="3413">EAEAEAEAEA18EAEAEA580148656C6C6F070148656C6C6F0718EAEAEA5802576F726C64<byte>
			<ext>ExtLab</ext>
		</byte>02576F726C64<byte>
			<ext>ExtLab</ext>
		</byte>4B0A4C<word>
			<val sect=".code">45</val>
		</word>4C<word>
			<ext>ExtLab</ext>
		</word>6C<word>
			<val sect=".code">45</val>
		</word>6C<word>
			<ext>ExtLab</ext>
		</word>20<word>
			<val sect=".code">45</val>
		</word>20<word>
			<ext>ExtLab</ext>
		</word>4C<word>
			<val sect=".code">45</val>
		</word>4C<word>
			<ext>ExtLab</ext>
		</word>6C<word>
			<val sect=".code">45</val>
		</word>6C<word>
			<ext>ExtLab</ext>
		</word>20<word>
			<val sect=".code">45</val>
		</word>22<word>
			<and>
				<ext>ExtLab</ext>
				<val>65535</val>
			</and>
		</word>
		<byte>
			<shr>
				<and>
					<ext>ExtLab</ext>
					<val>16711680</val>
				</and>
				<val>16</val>
			</shr>
		</byte>6911651175116D22117D2211792211611171112911251135112D22113D2211392211211131110A061116110E22111E22110F11001F11002F11003F11004F11005F11006F11007F11008F11009F1100AF1100BF1100CF1100DF1100EF1100FF11009000B000F00024112C22113000D00010000000115000700018D858B8C911C511D511CD2211DD2211D92211C111D111E011E411EC2211C011C411CC2211C611D611CE2211DE2211CA884911451155114D22115D221159221141115111E611F611EE2211FE2211E8C84C22116C2211202211A911A511B511AD2211BD2211B92211A111B111A211A611B611AE2211BE2211A011A411B411AC2211BC22114A461156114E22115E2211EA0911051115110D22111D22111922110111111148086828071117112711371147115711671177112A261136112E22113E22116A661176116E22117E22114060E911E511F511ED2211FD2211F92211E111F11138F87887119711A711B711C711D711E711F711851195118D22119D221199221181119111861196118E2211841194118C2211AAA8BA8A9A98007E6911651175116D22117D2211792211611171112911251135112D22113D2211392211211131110A061116110E22111E22119000B000F00024112C22113000D0001000005000700018D858B8C911C511D511CD2211DD2211D92211C111D111E011E411EC2211C011C411CC2211C611D611CE2211DE2211CA884911451155114D22115D221159221141115111E611F611EE2211FE2211E8C84C22116C2211202211A911A511B511AD2211BD2211B92211A111B111A211A611B611AE2211BE2211A011A411B411AC2211BC22114A461156114E22115E2211EA0911051115110D22111D221119221101111111480868282A261136112E22113E22116A661176116E22117E22114060E911E511F511ED2211FD2211F92211E111F11138F878851195118D22119D221199221181119111861196118E2211841194118C2211AAA8BA8A9A98007E6911651175116D22117D22117922116111711172112911251135112D22113D22113922112111311132110A061116110E22111E22110F11001F11002F11003F11004F11005F11006F11007F11008F11009F1100AF1100BF1100CF1100DF1100EF1100FF11009000B000F00024112C221134113C221189113000D00010008000005000700018D858B8C911C511D511CD2211DD2211D92211C111D111D211E011E411EC2211C011C411CC2211C611D611CE2211DE22113ACA884911451155114D22115D2211592211411151115211E611F611EE2211FE22111AE8C84C22116C22117C2211202211A911A511B511AD2211BD2211B92211A111B111B211A211A611B611AE2211BE2211A011A411B411AC2211BC22114A461156114E22115E2211EA0911051115110D22111D22111922110111111112114808DA5A6828FA7A071117112711371147115711671177112A261136112E22113E22116A661176116E22117E22114060E911E511F511ED2211FD2211F92211E111F111F21138F87887119711A711B711C711D711E711F711851195118D22119D2211992211811191119211DB861196118E2211841194118C2211641174119C22119E2211AAA814111C221104110C2211BA8A9A98CB007E6911651175116D22117D22117922116111711172112911251135112D22113D22113922112111311132110A061116110E22111E22119000B000F00024112C221134113C221189113000D00010008000005000700018D858B8C911C511D511CD2211DD2211D92211C111D111D211E011E411EC2211C011C411CC2211C611D611CE2211DE22113ACA884911451155114D22115D2211592211411151115211E611F611EE2211FE22111AE8C84C22116C22117C2211202211A911A511B511AD2211BD2211B92211A111B111B211A211A611B611AE2211BE2211A011A411B411AC2211BC22114A461156114E22115E2211EA0911051115110D22111D22111922110111111112114808DA5A6828FA7A2A261136112E22113E22116A661176116E22117E22114060E911E511F511ED2211FD2211F92211E111F111F21138F878851195118D22119D2211992211811191119211DB861196118E2211841194118C2211641174119C22119E2211AAA814111C221104110C2211BA8A9A98CB007E6911650075006D22117D22117922116100710072006F3322117F33221167007700630473042911250035002D22113D22113922112100310032002F3322113F33221127003700230433040A060016000E22111E22119000B000F00024002C221134003C221189113000D00010008000008200005000700018D858B8C911C500D500CD2211DD2211D92211C100D100D200CF332211DF332211C700D700C304D30402E01100E400EC2211C01100C400CC2211C600D600CE2211DE22113ACA884911450055004D22115D22115922114100510052004F3322115F3322114700570043045304E600F600EE2211FE22111AE8C8DC22114C22116C22117C221122332211202211FC2211A911A500B500AD2211BD2211B92211A100B100B200AF332211BF332211A700B700A304B304A21100A600B600AE2211BE2211A01100A400B400AC2211BC22114A460056004E22115E2211441122541122EA0911050015000D22111D22111922110100110012000F3322111F3322110700170003041304F42211D41162<word>
			<val sect=".code">2350</val>
		</word>488B0B4B08DA5A68AB2B28FA7AC2302A260036002E22113E22116A660076006E22117E2211406B60E911E500F500ED2211FD2211F92211E100F100F200EF332211FF332211E700F700E304F30438F878E230850095008D22119D22119922118100910092008F3322119F3322118700970083049304DB860096008E2211840094008C2211640074009C22119E2211AAA85B1B7B14001C221104000C22113BBA8A9A9B98BBCB42EBFBA942A24241A04342AF000001AD0000AD2400A504007E027F6911651175116D22117D22117922116111711172116F3322117F33221167117711630473042911251135112D22113D22113922112111311132112F3322113F33221127113711230433040A061116110E22111E22119000B000F00024112C221134113C221189113000D00010008000008200005000700018D858B8C911C511D511CD2211DD2211D92211C111D111D211CF332211DF332211C711D711C304D30402E01100E411EC2211C01100C411CC2211C611D611CE2211DE22113ACA884911451155114D22115D22115922114111511152114F3322115F3322114711571143045304E611F611EE2211FE22111AE8C8DC22114C22116C22117C221122332211202211FC2211A911A511B511AD2211BD2211B92211A111B111B211AF332211BF332211A711B711A304B304A21100A611B611AE2211BE2211A01100A411B411AC2211BC22114A461156114E22115E2211441122541122EA0911051115110D22111D22111922110111111112110F3322111F3322110711171103041304F42211D41162<word>
			<val sect=".code">1770</val>
		</word>488B0B4B08DA5A68AB2B28FA7AC2302A261136112E22113E22116A661176116E22117E2211406B60E911E511F511ED2211FD2211F92211E111F111F211EF332211FF332211E711F711E304F30438F878E230851195118D22119D22119922118111911192118F3322119F3322118711971183049304DB861196118E2211841194118C2211641174119C22119E2211AAA85B1B7B14111C221104110C22113BBA8A9A9B98BBCB42EBFBA942A24241A043426911000000651175116D22117D22117922116111711172116F3322117F33221167117711630473042911000000251135112D22113D22113922112111311132112F3322113F33221127113711230433040A061116110E22111E22119000B000F00024112C221134113C221189110000003000D00010008000008200005000700018D858B8C911000000C511D511CD2211DD2211D92211C111D111D211CF332211DF332211C711D711C304D30402E011E411EC2211C011C411CC2211C611D611CE2211DE22113ACA884911000000451155114D22115D22115922114111511152114F3322115F3322114711571143045304E611F611EE2211FE22111AE8C8DC22114C22116C22117C221122332211202211FC2211A911000000A511B511AD2211BD2211B92211A111B111B211AF332211BF332211A711B711A304B304A211A611B611AE2211BE2211A011A411B411AC2211BC22114A461156114E22115E2211441122541122EA0911000000051115110D22111D22111922110111111112110F3322111F3322110711171103041304F42211D41162<word>
			<val sect=".code">1189</val>
		</word>488B0B4B08DA5A68AB2B28FA7AC2302A261136112E22113E22116A661176116E22117E2211406B60E911000000E511F511ED2211FD2211F92211E111F111F211EF332211FF332211E711F711E304F30438F878E230851195118D22119D22119922118111911192118F3322119F3322118711971183049304DB861196118E2211841194118C2211641174119C22119E2211AAA85B1B7B14111C221104110C22113BBA8A9A9B98BBCB42EBFBA944434241A244A045AF000001AD0000AD2400A534007E027FA00098A2000A089001E828D0F8C8C080F00280EE</section>
	<section name=".data" size="53">0102030B41424348656C6C6F20576F726C640D0A<byte>
			<and>
				<val sect=".data">22</val>
				<val>255</val>
			</and>
		</byte>
		<byte>
			<and>
				<shr>
					<val sect=".data">22</val>
					<val>8</val>
				</shr>
				<val>255</val>
			</and>
		</byte>010002000300<word>
			<val sect=".data">31</val>
		</word>0800010000000200000003000000<word>
			<and>
				<val sect=".data">44</val>
				<val>65535</val>
			</and>
		</word>
		<byte>
			<shr>
				<and>
					<val sect=".data">44</val>
					<val>16711680</val>
				</and>
				<val>16</val>
			</shr>
		</byte>
		<word>
			<and>
				<ext>ExtLab</ext>
				<val>65535</val>
			</and>
		</word>
		<byte>
			<shr>
				<and>
					<ext>ExtLab</ext>
					<val>16711680</val>
				</and>
				<val>16</val>
			</shr>
		</byte>
		<word>
			<and>
				<val sect=".code">45</val>
				<val>65535</val>
			</and>
		</word>
		<byte>
			<shr>
				<and>
					<val sect=".code">45</val>
					<val>16711680</val>
				</and>
				<val>16</val>
			</shr>
		</byte>
	</section>
	<section name=".code" addr="0000E000" size="326">90034C09E1EAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA0A4C00E090FEB0034C00C0B0F790034C00C0F0F0D0034C00C030E910034C00C0D0E2F0034C00C010DB30034C00C050D470034C00C070CD50034C00C080C64C00C0</section>
	<gbl>GblLab<val sect=".code">45</val>
	</gbl>
</module>
Expressions with <byte> or <word> are calculated by the linker and inserted into the generated binary.
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
beethead
Posts: 9
Joined: 03 Dec 2019

Re: Linker Resources

Post by beethead »

One part of the linking process that has me concerned is in regards to code/data being placed in zero or direct page. If the assembler generates object code using absolute addressing, by default, and then the linker comes along and places the code/data into zero or direct page, ideally the opcode byte would have to be changed and then the space allocated for the absolute address needs to be truncated by one byte. That removal of one byte means the rest of the object code would be desynchronized. The assembler could be told by way of directives that the code/data will be placed into zero or direct page so that it generates the proper object code but that defeats the purpose of the linker.

This seems to be more of a problem for the 65816 and its direct page usage.
User avatar
cjs
Posts: 759
Joined: 01 Dec 2018
Location: Tokyo, Japan
Contact:

Re: Linker Resources

Post by cjs »

beethead wrote:
One part of the linking process that has me concerned is in regards to code/data being placed in zero or direct page.
I have limited experience with this, but here's how it works with ASxxxx, or at least how I do it. (There are more details in my personal notes on ASxxxx which may be faster to read than going into the actual documentation.)

Code and data can be in separate areas; same-named areas from different files are considered all part of one area by the linker. The default area is _CODE which is relocatable and and concatenated (i.e., each _CODE area from each object file will be placed in memory after the previous one).

I add an area called ZP which is absoute and has the PAG attribute set to give me a warning if the size at link time exceeds 256 bytes.

Code: Select all

            .area ZP  (abs,pag)
            .area   _CODE
At whatever points in the file are convenient I can then declare further storage in the zero page:

Code: Select all

tripleA:    sta *temp       ; "*" indicates direct (ZP) addressing mode
            clc
            adc *temp
            adc *temp
            rts

            .area ZP
temp:       .ds     1
            .area _CODE
When linking, I tell the linker to locate the ZP area at $0000. Thus, everything declared to be in the ZP area will be in the zero page (or the linker will find more than 256 bytes of storage allocated in the ZP area and halt with an error).

For processors like the 6809 and 65816 where the direct page can be anywhere in memory there's a .setdp [BASE[,AREA]] directive to tell the assembler at what address the direct page is placed, though of course the programmer is still responsible for writing whatever code is necessary to put it there at run time.

Code that accesses temp with absolute (2-byte) addressing is fine regardless of whether temp is in the zero page or not. Code that accesses it with direct (1-byte) addressing will be flagged by the linker as an error if temp is assigned to an address >$FF during the link.

The AS6502 assembler currently isn't (in most cases) able to figure out automatically whether an access should be able to use direct rather than absolute addressing, so you need to mark those manually as above. Even if it did do this it would be rather hit-or-miss because there's no way (that I can see) to tell the assembler that you expect a global from another (separately-assembled) file to be located at a zero-page address. The linker definitely doesn't change the opcodes after assembly; that would kinda make it an assembler, too. I suppose it would be possible to do this, but I've never seen anything that does. (This kind of thing is actually one reason why I'm looking at moving away from separate-assembly/link to whole-program assembly.)
Curt J. Sampson - github.com/0cjs
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Linker Resources

Post by BigEd »

(Welcome, beethead!)
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Linker Resources

Post by BigDumbDinosaur »

cjs wrote:
6502- and 65816-specific...
Commodore's DevPak editor/assembler for the C-128 used a linker. Although it added an extra step to producing a usable binary, the linker also allowed assembling for a part of the memory map that would not be easily accessible at assembly time, e.g., the stack. Almost all of my 128 development was assembled with a modified copy of the DevPak assembler that directly wrote the binary to disk.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
Post Reply