endlos99 / xdt99

xdt99: TMS 99xx Cross-Development Tools
http://endlos99.github.io/xdt99
GNU General Public License v3.0
52 stars 8 forks source link

Linker sometimes replaces value from REF statement with zeros. #46

Closed bkrug closed 1 year ago

bkrug commented 1 year ago

Thanks for the work that maintaining this assembler must entail.

I think I've found a bug in the linker, and I've created this repo to demonstrate it. I am in the habit of assembling source files into small object files first, and linking them together into large object files later. When the first assemblable word in a source file is a value that comes from a REF statement, that first word is rendered as >0000 in the larger object file.

See the file DISPNUM.asm. I would expect the START routine to display the below "expected" values, but instead it displays the below "actual" output.

Expected:

  1234
  5678
  9ABC
  1234
  5678
  9ABC

Actual:

  0000
  5678
  9ABC
  1234
  5678
  9ABC

The workaround for this bug is simple; begin each source file with either exectuable code, or a data value that does not come from a REF. Sometimes I forget about this bug however, and it takes me a while to track down the problem.

To run the code in the above repo, assemble the files using the same commands that you see in "assm.ps1". Then, load LINKED.obj from E/A 3, and type "START" as the program name.

endlos99 commented 1 year ago

Thanks for your bug report! This bug is actually not so simple.

In the object code, references are included with a tag like 40038SYM___, where SYM is the referenced symbol and >38 is the address where the SYM is referenced. Since SYM can be referenced more than once, the value at >38, which will be overwritten at link time, contains the address of the next reference, and so on, until this value is 0.

By extension, and I've confirmed this with E/A, if a REF'ed symbol is not referenced at all, it is listed with 0000 or address >0.

Unfortunately, this implies that it is impossible to differentiate between an unused reference and a reference at address >0. (Had TI decided to use XXXX instead of 0000 in the tag, this would not be an issue at all.) This issue is exacerbated by the fact that the xas99 linker relocates each relocatable segment to >0 during normalization. I'll have to see if I can choose a different address instead.

endlos99 commented 1 year ago

Actually, xas99 doesn't relocate to >0, it's just the default address that's overwritten immediately for any object code created by E/A or xas99. What I've implemented instead with the latest version 3.6.3 is to issue a warning during assembly if xas99 sees a reference at address >0.

Should you ever experience this bug again without getting this warning, please create another issue. Thanks again for your help!