6502 - An welcher Adresse laufe ich?

  • Konkret geht es um 6510 Assembler (C64).



    Die Motorola 6809 hat mit relokatiblen Code kein Problem.

    • es gibt relative Sprünge mit 16 Bit Distanz
    • es gibt relativen Unterprogramm Aufruf: BSR

    Insofern kann ich da Code schreiben, der an jeder Adresse laufen kann.

    Mich interessiert, was man in dieser Richtung mit der 6502/6510 machen könnte, trotz aller Einschränkungen dieser Architektur.



    Sagen wir mal, da ist ein Maschinen Programm, das an die falsche Adresse geladen und da gestartet wird.

    Was für Möglichkeiten hat der Code?


    Es ist für eine 6502 CPU ja nicht mal möglich herauszufinden, an welcher Adresse ich gerade laufe.

    Oder doch?



    Vorschlag 1:

    • Ein RTS an eine bekannte Adresse schreiben.
    • JSR auf diese Adresse machen
    • SP manipulieren und PC vom Stack lesen

    Geht es irgendwie anders vielleicht besser oder einfacher?

  • Die von Dir genannte Methode um die eigene Lokation zu ermitteln ist die gängige (wird z.B. von Apple II Slot Firmware so gemacht). Dort wird ein bekanntes RTS im System ROM benutzt.


    6502 Code zu relozieren ist nicht trivial, aber durchaus nicht völlig abwegig. Dabei gibt es meiner Meinung nach grundsätzlich zu entscheiden, ob der Code für den Zweck entwickelt wird/wurde oder nicht.


    Im ersteren Fall wird man auf die eine oder andere Weise Metadaten erzeugen, die bei der Relozierung helfen. Dann ist weiter zu entscheiden, ob man diese Metadaten in den Code einbaut oder ob sie neben dem Code vorliegen.


    Im zweiteren Fall benötigt man einen minimalen Dissassembler. Der geht den Code durch und findet die absoluten Referenzen. Normalerweise ist es leicht zu entscheiden, ob sich eine absolute Referenz auf das eigene Programm oder das System ROM bezieht. Auf selbst modifzierenden Code verzichtet man der Einfachheit halber in einen zu relozierenden Programm lieber. Dann kann sich der Dissassembler auf JMP/JSR beschränken.


    Just my two cents.

  • Mich interessiert, was man in dieser Richtung mit der 6502/6510 machen könnte, trotz aller Einschränkungen dieser Architektur.

    Joa, tut immer ziemlich weh, du landest halt bei indirekten Sprungtabellen irgendwo im Code oder in der Assembler-Makrohoelle :)


    Vorschlag 1:

    Ein RTS an eine bekannte Adresse schreiben.
    JSR auf diese Adresse machen
    SP manipulieren und PC vom Stack lesen

    Klingt ziemlich richtig...

    Code
    PC = $23
    
    PLA
    STA PC ; erstes Byte vom Stack lesen
    PLA
    STA PC+1 ; zweites Byte vom Stack lesen
    
    PHA ; zweites Byte wieder auf den Stack pushen
    LDA PC ; erstes Byte wieder laden
    PHA ; erstes Byte wieder auf den Stack pushen

    und dann musste halt den ermittellten Wert in PC nochmal um die 2 subtrahieren, die dir JSR draufpackt, damit es danach weiterspringt...

    Schon ziemlich umstaendlich, ja.

  • Beim 8080 (CP/M) und zahllosen früheren Minicomputersystemen hatte man dasselbe Problem, dass absolute Adressen im Code durchscheinen. Der gängige Weg dafür ist es, ein Object-File-Format zu erzeugen, welches relokatible Adressen aller Art markiert - OMF, COFF, Intel-OBJ/Hex oder Motorola S1/S2/S9-Format und diverse andere. Beim 650x gibt es nichts Standardisiertes. Das ist eigentlich der Kardinalfehler - ein netter Prozessor, aber keine verbreitetes Infrastruktur seitens des Herstellers.
    Der 6502 ist nicht auf Relokatibilität hin designed; selbst sein Vater, der 6800 war da besser - es gibt im 6502 zwar relative Sprünge, aber z.B. kein BRA/BSR, welche recht einfach realisierbar gewesen wären. Der Stack ist an 0x100-0x1ff festgenagelt, die Zero-Page ist eben bei 0x00nn. Man hat auf Register verzichtet, welche direkt 16-bit-Adressen speichern konnten. Der 8080 hatte solche, der 6800 zumindest mit SP und X zwei davon. Die 128 indirekten Paare in der Zero-Page sind nur ein müder Ersatz, wenn sie nur 8-Bit-portionsweise befüllt werden können. Beim Disassemblieren des HP35 (der einen embedded 6502-Core enthält) war mir das schmerzlich aufgefallen - der Code ließe sich mit 16-Bit-Instruktionen massiv kürzen. Beim 6809 hat man dazugelernt.

  • Der 6502 ist nicht auf Relokatibilität hin designed; selbst sein Vater, der 6800 war da besser - es gibt im 6502 zwar relative Sprünge, aber z.B. kein BRA/BSR, welche recht einfach realisierbar gewesen wären. Der Stack ist an 0x100-0x1ff festgenagelt, die Zero-Page ist eben bei 0x00nn. Man hat auf Register verzichtet, welche direkt 16-bit-Adressen speichern konnten. Der 8080 hatte solche, der 6800 zumindest mit SP und X zwei davon. Die 128 indirekten Paare in der Zero-Page sind nur ein müder Ersatz, wenn sie nur 8-Bit-portionsweise befüllt werden können.


    ... der Chip kostete $25 , der nächste vergleichbare so was ab $200 bis eher $400 ...


    (außerdem konnten sie es ja nun auch nicht 1:1 nachbauen)

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries

  • Sagen wir mal, da ist ein Maschinen Programm, das an die falsche Adresse geladen und da gestartet wird.

    Was für Möglichkeiten hat der Code?


    Selbstmodifikation ?



    Es ist für eine 6502 CPU ja nicht mal möglich herauszufinden, an welcher Adresse ich gerade laufe.

    Oder doch?

    Vorschlag 1:

    Ein RTS an eine bekannte Adresse schreiben.
    JSR auf diese Adresse machen
    SP manipulieren und PC vom Stack lesen

    Geht es irgendwie anders vielleicht besser oder einfacher?


    Normalerweise ist da Ladeadresse ja bekannt und man kann die irgendwie herausbekommen. Dann wäre das evtl eine Möglichkeit da immer fixe Werte auf die Sprünge zu addieren. Ist aber wohl mindestens genauso hakelig.


    Man könnte damit auch z.B. eine Sprungtabelle pflegen, die nur einmal am Anfang aktualisiert wird und die eigentlichen Sprünge springen dann über die Tabelle (also JMP Eintrag#4 oder sowas). Dann hat man das "Modifizieren" gewissermaßen outgesourced und Assembler sollten sowas eigentlich gut unterstützen ohne daß man sich groß weiter drum kümmern muß, wenn man es einmal gebaut hat (Makro).

    -- 1982 gab es keinen Raspberry Pi , aber Pi und Raspberries