APPLICATIONSPROGRAMMATION ★ Vertrackte Warte-Takte ★

Relokalisator (Computer Technik)Applications Programmation
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

Einfacher Relokalisator für Schneider, Spectrum und andere Z80-Systeme

Es ist schon ein Kreuz: Solange man nur ein Maschinencode-Utility im Speicher hat, gehl alles gut, aber wehe, wenn es mehr werden! Wer zuerst kommt, mahlt zuerst, und alle anderen Routinen, die man danach einladen will, spielen ‘Die Reise nach ROM': Wenn ihr vorgesehener Adreß-Bereich bereits durch andere Programme auch nur teilweise belegt ist, muß man auf sie verzichten.

Solchen Ärger kann man sich ersparen, wenn man seine Maschinencode-Programme relokalisierbar (verschiebbar) macht. Dann kann man sie immer da hinlegen, wo Platz ist, unabhängig von der Position, an der sie einmal geschrieben wurden.

Das Problem beim Verschieben sind die absoluten Adressen, sei es von Variablen oder von Unterprogrammen, die auf eine Adresse Bezug nehmen. Bei relativen Adressen wird dagegen die Entfernung zur Position des adressierenden Befehls angegeben (JR± Offset). Wird ein Mcode-Programm an einer anderen Stelle eingeladen als an die, für die es geschrieben wurde, stimmen die absoluten Adressen nicht mehr; nur noch die relativen, denn Abstände innerhalb des Programmes ändern sich beim Verschieben ja nicht.

Benutzt man aber in einem verschiebbaren Programm absolute Adressen, so muß man diese vor dem ersten Aufruf an die tatsächliche Programm-Position anpassen. Dazu braucht man ein Verschiebe-Programm und eine Tabelle, in der alle Stellen eingetragen sind, an denen absolute Adressen Vorkommen.

Schieben

Listing 1 zeigt einen solchen Relokalisator, wie er für alle Z80-Systeme verwendbar ist. Er wird bei der Programmentwicklung vor das eigentliche Programm ‘gehängt' und mit

diesem zusammen abgespeichert. Nachher lädt man das Programm an einer beliebigen Stelle ein und ruft den Relokalisator auf, der dann alle absoluten Adressen anpaßt.

2-Byte-'Befehl' :

X1: EQU $-1
DEFW adresse

3-Byte-Befehles:

X2: LD HL,adresse
X3: LD (adresse),HL
X4: LD BC,adresse
X5: LD (adresse),a
X6: CALL adresse
X7: JP adresse

4-Byte-Befehle:

X8: EQU $+1
LD BC,(adresse)
X9: EQU $+1
LD (adresse),de

Tabelle I. So markiert man im Assembler die Reterenzadressen

Dieser muß zuerst einmal feststellen, wo das Programm überhaupt liegt (Zeilen 15—20). Dazu ruft er einfach irgendeine Stelle im RAM oder ROM auf, die garantiert immer ein ‘RET' enthält. Beim Schneider CPC wäre das zum Beispiel Adresse 15 (OFh) oder beim ZX-Spectrum Adresse 82 (52h). Bei Unterprogramm-Aufrufen legt der Prozessor die Return-Adresse, das ist die Adresse des nächsten Befehls, auf den Maschinenstapel. Im Listing ist diese Stelle mit dem Label ‘STELLE' markiert. Mit dem Return aus dem Dummy-Unterprogramm wird dieser Stack-Eintrag aber wieder verbraucht. Man muß daher den Stapelzeiger ‘SP' wieder um zwei Stellen erniedrigen, um mit ‘POP HL' die Rücksprungadresse ein zweites Mal vom Stack holen zu können. Sollte aber ausgerechnet vor dem zweiten ‘DEC SP' ein Interrupt dazwischenfunken, wäre die Rücksprungadresse zerstört. Deswegen wird für die Dauer dieser Operation der Interrupt abgestellt.

Als nächstes bestimmt das Programm den Abstand zur ursprünglichen Adreßlage (Zeilen 24—27). Dazu zieht man den Original-Wert von ‘STELLE' von dessen tatsächlicher Position ab und erhält hiermit die Entfernung, um die das Programm verschoben wurde. Dieser Wert kann, je nach Ver-schiebe-Richtung, positiv oder negativ sein. Er wird für den Rest des Programmes im Register DE gespeichert. Um nun zu einer absoluten Adresse den neuen Wert zu berechnen, muß man zu deren alten Wert immer diesen Offset addieren.

Die erste absolute Adresse, die angepaßt werden muß, ist die Adresse der Tabelle selbst, damit der Relokalisator sie überhaupt findet. Das geschieht in den Zeilen 31 und 32. Die tatsächliche Adresse ist nun im HL-Register, und das dient im weiteren Verlauf des Programmes als Zeiger auf die Tabellen-Einträge.

In Zeile 39 beginnt nun die Schleife über alle Einträge: Zuerst wird eine Adresse aus der Tabelle geholt und HL gleich weitergestellt. Diese Adresse ist nun die Original-Adresse einer Stelle, an der die absolute Adressierung verwendet wurde.

Als Endmarke der Tabelle ist der Eintrag 0000h vorgesehen, was die Routine in den Zeilen 46—48 testet. In diesem Fall verzweigt sie in irgendeine weitere Initialisierungs-Routine. Gibt es keine, kann man hier ein RET Z einsetzen. Benutzt man hierfür aber einen absoluten Sprung (JP Z.xxxx), muß man natürlich auch diesen relokalisieren.

Andernfalls geht es weiter: In den Zeilen 52 bis 54 bestimmt das Verschiebeprogramm, wo die Stelle, an der die absolute Adressierung verwendet wurde, jetzt tatsächlich liegt. Hierfür kopiert sie den Offset aus dem DE-Register ins IX-Register und addiert den Original-Wert dazu.

Nun zeigt IX auf die absolute Adresse. Aus einem Grund, der nachher noch erläutert wird, nicht direkt, sondern auf eine Stelle davor.

Jetzt endlich erfolgt die Adreßänderung (Zeilen 58—64). Zuerst werden die niederwertigen Bytes von Offset und Original-Adresse addiert und wieder abgespeichert und dann die höherwertigen, diesmal aber mit ‘ADC', um einen eventuellen Übertrag zu berücksichtigen.

In Zeile 66 springt das Programm wieder an den Schleifenanfang, um die nächste Adresse anzupassen.

Mit Aufruf dieses Relokalisators wird das Programm also an seine tatsächliche Lage angepaßt. Er darf allerdings nur einmal aufgerufen werden, da der Offset sonst ein zweites Mal zu den Adressen addiert würde.

Schließlich kann man den Platz, den der Relokalisator samt Tabelle einnimmt, nachher wieder für andere Programme benutzen, er wird hier ja nicht mehr benötigt.

Entwickeln

Schreibt man ein neues Programm, assembliert man es zunächst immer ganz normal für eine beliebige, feste Startadresse (Origin). Dort wird es dann ausgetestet, bis es läuft.

Steht das Programm, ‘linkt' man den Relokalisator davor. Dann muß man die Tabelle eingeben. Das ist der langweiligste Teil des Ganzen und ist doch mit der größten Sorgfalt durchzuführen.

Zunächst durchsucht man das ganze Programm systematisch nach allen Stellen, an denen eine absolute Adresse vorkommt: Das sind zum Beispiel folgende Befehle:

CALL xxxx
JP xxxx
LD HL,(xxxx)
LD (xxxx),DE

Einige Befehle sind zweideutig, sie können eine absolute Adresse benutzen:

LD HL,xxxx
DEFW xxxx

Es kommt hier auf den Programm-Zusammenhang an, was der Zahlenwert bedeuten soll.

Jede gefundene absolute Adresse wird dann noch nach folgendem Kriterium beurteilt:

Liegt die Adresse außerhalb des Programms und kann sie sich überhaupt nicht ändern, dann darf man sie natürlich nicht relokalisieren. Solche Adressen sind in der Hauptsache Systemvariablen und Unterprogramme im Betriebssystem. Liegt diese Adresse aber im Programm, so muß sie in die Tabelle eingetragen werden.

Zu diesem Zweck markiert man die Stelle, an der die Adresse benutzt wurde (die adressierende, nicht die adressierte Stelle!), mit einem Label und trägt dieses Label in die Tabelle ein.

Markieren

Da es sich in den meisten Fällen um einen 3-Byte-Befehl handelt, ist es sinnvoll, nicht die Stelle direkt zu markieren: In die Tabelle wird immer die Adresse der Stelle minus eins eingetragen. Damit kann man das Label meistens vor den Befehl setzen. Bei 4-Byte-Befeh-len und bei Adressen in Data-Bereichen (mittels DEFW) geht das nicht, hier muß man auf die umständlichere Methode mit ‘EQU' zurückgreifen.

ln Tabelle 1 sind einige typische Befehle mit Labels für den Relokalisator versehen worden. Beim ‘Labein' sollte man außerdem:

  1. eine einheitliche Nomenklatur verwenden, um nachher die Relokalisator-Labels von den ‘normalen' unterscheiden zu können. Ein Durchnumerieren der Label ist sinnvoll, dann wird auch keines in der Tabelle vergessen: Man kann beispielsweise die Label-Namen X0 bis X99999 vorsehen.
  2. sich nicht verlocken lassen, ein ‘normales' Label mitzubenutzen, weil es schon an der richtigen Stelle steht. In diesem Fall lieber eine Stelle im Programm mit zwei Labels versehen, dem ‘normalen' und dem für den Relokalisator. Sonst geht die Übersicht schnell verloren!

Hat man dann alle Stellen markiert und in die Tabelle des Relokalisators eingetragen, geht es ans letzte Austesten.

Läuft das Programm nicht, wenn man es an anderen Stellen einlädt, kann es daran liegen, daß man eine Stelle vergessen, oder auch zuviel markiert hat. Oder man hat einmal daneben ‘gelabelt' und zum Beispiel ein LD BC,(xxxx) direkt und nicht mit ‘EQU' markiert. Eventuell hat man auch vergessen, ein Label in die Tabelle einzutragen.

Günter Woigk, c't

★ PUBLISHER: Computer Technik (c't)
★ YEAR: 1985
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LiCENCE: LISTING
★ AUTHOR: Günter WOIGK
★ INFO: Lisling I. Der Relokalisator arbeitet mit einer Referen/tabelle, die der Assembler erstellt.
 

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» Relokalisator    (Computer  Technik)    (ASM-SOURCE)    GERMAN    LISTINGDATE: 2024-03-08
DL: 20
TYPE: PDF
SiZE: 53Ko
NOTE: Supplied by archive.org ; 1 page/PDFlib v1.6

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » Reloc (CPC Amstrad International)
» Applications » Relocate Code Laser Genius
» Applications » MC-Relocator (Schneider Magazin)
» Applications » Z80 Relocator (Moj Micro)
» Applications » Code Relocator
» Applications » Relocator v1.0 (CPC Amstrad International)
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 310 millisecondes et consultée 80 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.