Hallo,
seit heute Morgen versuche ich einen alten Assembler code wieder in
einer IDE zum laufen zu bekommen.
Ich kann den Code übersetzen, aber wenn ich "Build All" ausführen
möchte, bringt mir mein Linker einen Fehler, mit dem ich erstmal nichts
anfangen kann.
--> Code Space Overlap at address: 0FF8
ich habe schon im Linker PDF und auf google nachgeschaut aber habe
leider keine näheren Informationen gefunden, wodurch dieser Fehler
verursacht wird bzw. wie man ihn beheben kann.
Wodurch sntstehen solche Fehler ?
csol schrieb:> Hallo,>> seit heute Morgen versuche ich einen alten Assembler code wieder in> einer IDE zum laufen zu bekommen.> Ich kann den Code übersetzen, aber wenn ich "Build All" ausführen> möchte, bringt mir mein Linker einen Fehler, mit dem ich erstmal nichts> anfangen kann.> --> Code Space Overlap at address: 0FF8>> ich habe schon im Linker PDF und auf google nachgeschaut aber habe> leider keine näheren Informationen gefunden, wodurch dieser Fehler> verursacht wird bzw. wie man ihn beheben kann.>> Wodurch sntstehen solche Fehler ?
Dein Linker soll wohl verschieden Codesegmente auf die gleiche Adresse
mappen.
Wahrscheinlich ist ein Codesegment grösser geworden und ragt in ein
anderes rein. Was an Adresse 0x0ff8 steht, sagt dir dein Map-File.
Dann überprüfe ich nochmals alle ORG Anweisungen in meinem Code.
Ist die Angehängte Datei eine solche Map-File ?
Dort steht leider nichts mit der Adresse 0FF8 drin.
csol schrieb:> Dann überprüfe ich nochmals alle ORG Anweisungen in meinem Code.>> Ist die Angehängte Datei eine solche Map-File ?> Dort steht leider nichts mit der Adresse 0FF8 drin.
Hmm... Anfänger?
Was steht hier?:
Hmm Anfänger, denke schon.
Habe gerade im Datenblatt des Controllers nachgeschaut. Die Adresse 0FF8
ist reserviert. Darf man also nicht verwenden.
In meinem Code gibt es aber nur zwei .ORG Anweisungen und die weisen
nicht auf die Adresse 0FF8 hin.
Einmal für den Start und einmal für die Interrupts.
Wie kann man nun vorgehen, um das Problem zu lösen ?
ist das Problem.
Wenn an 000FF0 ein Codestück anfängt, welches 000010 Bytes lang ist,
dann kann nicht an 000FF8 ein weiteres Codestück anfangen.
Denn 000FF0 plus 000010 macht 001000 und die Adresse 000FF8 liegt da
genau dazwischen.
Du hast im Prinzip dem Baggerfahrer gesagt, dass du ein Haus an der
Hausnummer 8 bauen willst nur blöderweise steht dort schon ein Wohnblock
dessen 16 Eingänge schon die Hausnummern 0 bis 15 belegen. Soll er jetzt
den WOhnblock mitten drinn einreissen, damit du bei 8 neu zu bauen
anfangen kannst?
Das diese Adresse bei dir im Code nicht direkt aufscheinen, glaub ich
dir. Nichts desto trotz musst du rückwärts verfolgen, wie diese
Doppelbelegung zu Stande kommt.
csol schrieb:> Hmm Anfänger, denke schon.> Habe gerade im Datenblatt des Controllers nachgeschaut. Die Adresse 0FF8> ist reserviert. Darf man also nicht verwenden.> In meinem Code gibt es aber nur zwei .ORG Anweisungen und die weisen> nicht auf die Adresse 0FF8 hin.>> Einmal für den Start und einmal für die Interrupts.>> Wie kann man nun vorgehen, um das Problem zu lösen ?
Der Code, der an Adresse 000FF0H geschrieben wird ist 10H lang, geht
also bis 001000H und ragt in 000FF8 hinein.
Was ist das denn für ein Controller?
Es sieht so aus, als wäre der Code, der bei "Start" anfängt zu lang.
Kannst du mal die ORG-Zeilen posten.
csol schrieb:> Hmm Anfänger, denke schon.> Habe gerade im Datenblatt des Controllers nachgeschaut. Die Adresse 0FF8> ist reserviert. Darf man also nicht verwenden.> In meinem Code gibt es aber nur zwei .ORG Anweisungen und die weisen> nicht auf die Adresse 0FF8 hin.>> Einmal für den Start und einmal für die Interrupts.>> Wie kann man nun vorgehen, um das Problem zu lösen ?
Es kann auch sein, dass es noch Linker-Mapping-Files gibt, die dem
Linker sagen, wo die Codesegmente hinkommen sollen.
Das ganze ist ein bischen "kompliziert", zumindest für einen "Anfänger".
Deswegen ist das so mit dieser Ferndiagnose eine Sache.
Kannst du mal den Sourcecode und die Linker-Files posten?
Edit: UUuups zu spät.
csol schrieb:> Ah ok, vielen Dank schonmal. Das macht Sinn.> Gerne poste ich euch das Dateblatt und die Codesegmente für die .ORG>>
1
; ----- interrupt-vectoren setzen
2
>
3
> .org 0ff0h ; [gpa 183]
4
>
5
> nop ; vector 4 timer / adc
6
> reti
7
>
8
> jp irq_arti ; vector 3 artimer
9
>
10
> jp irq_pc ; vector 2 port c / spi
11
>
12
> nop ; vector 1 port a / port b
13
> reti
14
>
15
> nop ; [gpa 183]
16
> nop
17
> nop
18
> nop
19
>
20
> nop ; vector 0 nmi
21
> reti
22
>
23
> jp main ; reset
Das hat schon mal funktioniert?
Datenblatt Seite 84 (hast du sicher schon selbst gesehen). FF8H ist
tasächlich reserviert. Du kannst also nicht einfach deinen Speicher mit
"nops" füllen, damit zum NMI-Interrupt kommst.
--> NOPs weglassen und für den NMI ein neues ORG setzen.
Ich habe mir eben eine weitere Textdatei von meinem Linker angeschaut.
Diesen Ausschnitt meine ich :
1
1285 ; ----- interrupt-vectoren setzen
2
1286
3
------ ------------ 1287 CSEG AT 0ff0h ; [gpa 183]
4
1288
5
0FF0 04 1289 nop ; vector 4 timer / adc
6
0FF1 4D 1290 reti
7
1291
8
0FF2 0900 F 1292 jp irq_arti ; vector 3 artimer
9
1293
10
0FF4 0900 F 1294 jp irq_pc ; vector 2 port c / spi
11
1295
12
0FF6 04 1296 nop ; vector 1 port a / port b
13
0FF7 4D 1297 reti
14
1298
15
0FF8 04 1299 nop ; [gpa 183]
16
0FF9 04 1300 nop
17
0FFA 04 1301 nop
18
0FFB 04 1302 nop
19
1303
20
0FFC 04 1304 nop ; vector 0 nmi
21
0FFD 4D 1305 reti
22
1306
23
0FFE 0900 F 1307 jp main ; reset
24
1308
25
1309
Die Interruptroutine geht anscheinen in die Adresse 0FF8 hinein. Sehe
ich das richtig ? Aber da ab 0FF8 für den Controller reserviert ist,
kommt es zu Fehlern ?
csol schrieb:> Die Interruptroutine geht anscheinen in die Adresse 0FF8 hinein. Sehe> ich das richtig ? Aber da ab 0FF8 für den Controller reserviert ist,> kommt es zu Fehlern ?
Ja, das Listing ist eine gute Hilfe. Jetzt weisst du welche NOPs ich
meine...
Daniel V. schrieb:> csol schrieb:>> Die Interruptroutine geht anscheinen in die Adresse 0FF8 hinein. Sehe>> ich das richtig ? Aber da ab 0FF8 für den Controller reserviert ist,>> kommt es zu Fehlern ?>> Ja, das Listing ist eine gute Hilfe. Jetzt weisst du welche NOPs ich> meine...
ok, vielen Dank. Du hilfst mir sehr das zu verstehen.
Du hast mir weiter oben einen Lösungsvorschlag gepostet.
In der Interruptreoutine ein weiteres .org zu setzen.
Verstehe ich das richtig, dass ich mein Programm in die Interruptroutine
hieinsoll also an Adresse FF0 und ich dann sobald die Adressen von FF0
bis FF7 voll sind mit einem weiteren .org zum Beispiel an eine freie
Adresse springe ? Zum Beispiel im User program memory ?
Ja, der Code funktioniert. Zumindest hat er das mal.
Definiert denn dein Assembler keine symbolischen Konstanten für die 5
verfügbaren Interrupt Vektoren? Dieses "Ich fange bei 00F0 an und streue
zur Not einfach so viele NOP ein, bis ich wieder an der richtigen
Adresse bin" ist keine gute Idee.
Machs wenigstens so
1
.org 0ff0h ; ***** Interrupt source #4
2
nop ; vector 4 timer / adc
3
reti
4
5
.org 0ff2h ; ***** Interrupt source #3
6
jp irq_arti ; vector 3 artimer
7
8
.org 0ff4h ; ***** Interrupt source #2
9
jp irq_pc ; vector 2 port c / spi
10
11
.org 0ff6h ; ***** Interrupt source #1
12
nop ; vector 1 port a / port b
13
reti
14
15
.org 0ffch ; ***** Interrupt source #0
16
nop ; vector 0 nmi
17
reti
18
;
19
.org 0ffeh
20
jp main ; reset
Jeder Vektor kriegt sein eigenes .org welches ihn auf seine Adresse
festnagelt. Schöner wärs, wenn anstelle der Adressen in Zahlenform
symbolische Namen stehen würden, die dir bereits vom Assembler einfach
so zur Verfügung gestellt wurden. Dazu müsste man aber die
Assembler-Include Files durchsuchen, ob es sowas gibt.
Und nein, ORG springt nicht, sondern weist den Linker an, den Code an
eine bestimmte Stelle zu positionieren.
Edit: Da war mal wieder Karl Heinz schneller und "schöner" erklärt!
Karl Heinz Buchegger schrieb:> Definiert denn dein Assembler keine symbolischen Konstanten für die 5> verfügbaren Interrupt Vektoren? Dieses "Ich fange bei 00F0 an und streue> zur Not einfach so viele NOP ein, bis ich wieder an der richtigen> Adresse bin" ist keine gute Idee.>> Machs wenigstens so ....> Jeder Vektor kriegt sein eigenes .org welches ihn auf seine Adresse> festnagelt. Schöner wärs, wenn anstelle der Adressen in Zahlenform> symbolische Namen stehen würden, die dir bereits vom Assembler einfach> so zur Verfügung gestellt wurden. Dazu müsste man aber die> Assembler-Include Files durchsuchen, ob es sowas gibt.
Dann kann man aber die nops auch ganz weglassen... :-)
Daniel V. schrieb:>> Dann kann man aber die nops auch ganz weglassen... :-)
Ja, ich war am Ringen mit mir selbst, ob ich die restlichen NOP auch
gleich mit rausnehme.
Aber ganz ehrlich, so richtig sattelfest scheint mir der TO nicht zu
sein. Das scheint er nicht begriffen zu haben, worum es bei diesen
Interrupt-Vektoren geht. Um ihn nicht noch mehr zu verwirren hab ich es
gelassen.
Der Vollständigkeit halber
Vielen Dank an euch zwei für eure Mühe und die wirklich sehr
ausführliche Hilfe. Das hilft mir sehr weiter.
Ich werde mir das jetzt nochmal in Ruhe anschauen und versuchen das
besser zu verstehen.
Vielleicht schaffe ich es dann noch im laufe des Tages den Code zum
laufen zu bekommen.
Was mich dennoch irritiert, der Code liegt assembliert vor und läuft auf
den Controllern. Zumindest vermute ich, dass es sich dabei auch um
diesen Code handelt, da er der aktuellsten Version entspricht.
csol schrieb:> Vielen Dank an euch zwei für eure Mühe und die wirklich sehr> ausführliche Hilfe. Das hilft mir sehr weiter.> Ich werde mir das jetzt nochmal in Ruhe anschauen und versuchen das> besser zu verstehen.> Vielleicht schaffe ich es dann noch im laufe des Tages den Code zum> laufen zu bekommen.>> Was mich dennoch irritiert, der Code liegt assembliert vor und läuft auf> den Controllern. Zumindest vermute ich, dass es sich dabei auch um> diesen Code handelt, da er der aktuellsten Version entspricht.
Kann es sein, dass du den Compiler/Assembler aktuallisiert hast?
Eventuell weiß der Linker inzwischen (oder es wird ihm "gesagt"), dass
bei diesem Controller-Typ ein reservierter Bereich vorhanden ist. Eine
ältere Version hat das vielleicht noch gar nicht kontrolliert...??
Daniel V. schrieb:> Das hat schon mal funktioniert?> Datenblatt Seite 84 (hast du sicher schon selbst gesehen). FF8H ist> tasächlich reserviert. Du kannst also nicht einfach deinen Speicher mit> "nops" füllen, damit zum NMI-Interrupt kommst.> --> NOPs weglassen und für den NMI ein neues ORG setzen.
Sorry, ich meinte natürlich Seite 6 (Program Memory Map).
Daniel V. schrieb:> csol schrieb:>> Vielen Dank an euch zwei für eure Mühe und die wirklich sehr>> ausführliche Hilfe. Das hilft mir sehr weiter.>> Ich werde mir das jetzt nochmal in Ruhe anschauen und versuchen das>> besser zu verstehen.>> Vielleicht schaffe ich es dann noch im laufe des Tages den Code zum>> laufen zu bekommen.>>>> Was mich dennoch irritiert, der Code liegt assembliert vor und läuft auf>> den Controllern. Zumindest vermute ich, dass es sich dabei auch um>> diesen Code handelt, da er der aktuellsten Version entspricht.>> Kann es sein, dass du den Compiler/Assembler aktuallisiert hast?> Eventuell weiß der Linker inzwischen (oder es wird ihm "gesagt"), dass> bei diesem Controller-Typ ein reservierter Bereich vorhanden ist. Eine> ältere Version hat das vielleicht noch gar nicht kontrolliert...??
Hmm das gut möglich. Immerhin ist der Code mehr etwa 14 Jahre alt.
Aber müsste der Code dann nicht schon von vorn herein einen Fehler
haben, wenn im reservierten Bereich was drin steht ?
Daniel, eine Frage hätte ich noch an dich.
Du hast in einer vorherigen Antwort geschrieben, dass man die NOP nicht
nutzen darf um in dem NMI Bereich zu gelangen.
Wie kann man sich das vorstellen ? Wollte derjenige, der sie
hingeschrieben hat den Program Counter fortlaufen lassen oder wie soll
man mit NOP in den nmi Bereich gelangen ?
csol schrieb:> Daniel, eine Frage hätte ich noch an dich.> Du hast in einer vorherigen Antwort geschrieben, dass man die NOP nicht> nutzen darf um in dem NMI Bereich zu gelangen.>> Wie kann man sich das vorstellen ? Wollte derjenige, der sie> hingeschrieben hat den Program Counter fortlaufen lassen oder wie soll> man mit NOP in den nmi Bereich gelangen ?
Hier passiert eine Vermischung von Ablauf-Code und Adressreservierung.
Falls der Controller an die Addresse 0FF8H springt, dann läuft er bis
zum nächsten "reti". In diesem Fall wird der Program Counter
hochgezählt, richtig.
Gleichzeitig passiert aber noch eine Adressreservierung, wie du in
deinem Listing sehen kannst:
1
1285;-----interrupt-vectorensetzen
2
1286
3
------------------1287CSEGAT0ff0h;[gpa183]
4
1288
5
0FF0041289nop;vector4timer/adc
6
0FF14D1290reti
7
1291
8
0FF20900F1292jpirq_arti;vector3artimer
9
1293
10
0FF40900F1294jpirq_pc;vector2portc/spi
11
1295
12
0FF6041296nop;vector1porta/portb
13
0FF74D1297reti
14
1298
15
*0FF8041299nop;[gpa183]*
16
*0FF9041300nop*
17
*0FFA041301nop*
18
*0FFB041302nop*
19
1303
20
0FFC041304nop;vector0nmi
21
0FFD4D1305reti
22
1306
23
0FFE0900F1307jpmain;reset
24
1308
25
1309
Die Addressen von 0FF8h bis 0ffbh werden mit NOP belegt, so dass auf der
Addresse 0ffch der nmi zu liegen kommt.
Eigentlich ist aber der komplette Bereich 0ff8h bis 0ffbh reserviert und
somit diese NOPs an der Stelle verboten!
Wenn du eine bestimmte Adresse brauchst, dann nimmst du dafür ORG.
Ist das so verständlich?
Und schau noch mal in deinen Source Code.
Wahrscheinlich irgendwo ganz am Anfang schätze ich mal, wird es einen
.include
ode
.inc
oder so ähnlich geben, gefolgt von einem Dateinamen, in dem sich die
Bezeichnung deines Prozessors wiederspiegelt.
Dieses File machst du auf und suchst da drinnen, ob du die Adressen
0FF0H bzw. die anderen wiederfindest. Da wird es sicherlich einen
symbolischen Namen dafür geben. Und den verwendest du dann anstelle der
direkten Adressangabe in Hex-Zahlenform.
Das Ziel ist es, dass da steht (ich hab die Namen jetzt erfunden)
1
.org INTERRUPT_4_vec ; ***** Interrupt source #4
2
reti ; vector 4 timer / adc
3
4
.org INTERRUPT_3_vec ; ***** Interrupt source #3
5
jp irq_arti ; vector 3 artimer
6
7
.org INTERRUPT_2_vec ; ***** Interrupt source #2
8
jp irq_pc ; vector 2 port c / spi
9
10
.org INTERRUPT_1_vec ; ***** Interrupt source #1
11
reti ; vector 1 port a / port b
12
13
.org INTERRUPT_0_vec ; ***** Interrupt source #0
14
reti ; vector 0 nmi
15
;
16
.org RESET_vect
17
jp main ; reset
Denn die tatsächlichen Adressen in Zahlenform sollen dich ja gar nicht
interessieren. Du weisst nur, dass der Code für zb den Interrupt Vektor
0 an eine ganz bestimmte Stelle im Speicher muss, die den Namen
'INTERRUPT_0_vec' trägt (Name erfunden). Und genau das teilst du dann
auch mit dem .org dem Assembler mit.
Diese Namen kommen natürlich nicht einfach aus der Luft daher, sondern
die sind irgendwo mal definiert worden und die gibt dir der Hersteller
das Assemblers vor. Wenn er das getan hat, dann stehen die höchst
wahrscheinlich in einem vom Prozessor abhängigen Include File. Und dort
kann man sie finden, wenn es sie gibt.
In der Form ist das Ganze dann sauber und nach den Regeln der Kunst
gemacht und nicht so ein NOP-Amateuergefrickel, das nur dann 'zufällig'
funktioniert, wenn der Mond beim Programmschreiben günstig steht.