Forum: Mikrocontroller und Digitale Elektronik Code Space Overlap Fehler


von csol (Gast)


Lesenswert?

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 ?

von Daniel V. (danvet)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

>Wodurch sntstehen solche Fehler ?

Z.B. durch falsche ORG-Anweisungen.

MfG Spess

von csol (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Daniel V. (danvet)


Lesenswert?

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?:
1
    *********************************************************************
2
    *****************   P A G E      N U M B E R   32  ******************
3
    *********************************************************************
4
5
    TYPE     BASE       LENGTH    RELOCATION     CONSTRAINT  SEGMENT NAME
6
    ----     ----       ------    ----------     ----------  ------------
7
    CODE     000FF0H    000010H   ABSOLUTE       VECTOR      ?CO?IRRX36SK01
8
    
9
    CODE     000FF8H    000004H   ABSOLUTE       VECTOR      ?PR?Reserve?02

Das ist das Problem.

Als Tip: Bei Textfiles hilft es ungemein, wenn man nach dem zu findenden 
Text einfach suchen lässt (Ctrl-F). :-)

von csol (Gast)


Lesenswert?

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 ?

von Karl H. (kbuchegg)


Lesenswert?

Wie Daniel schon sagte:
Hier
1
    *********************************************************************
2
    *****************   P A G E      N U M B E R   32  ******************
3
    *********************************************************************
4
5
    TYPE     BASE       LENGTH    RELOCATION     CONSTRAINT  SEGMENT NAME
6
    ----     ----       ------    ----------     ----------  ------------
7
    CODE     000FF0H    000010H   ABSOLUTE       VECTOR      ?CO?IRRX36SK01
8
    
9
    CODE     000FF8H    000004H   ABSOLUTE       VECTOR      ?PR?Reserve?02

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.

von Daniel V. (danvet)


Lesenswert?

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.

von csol (Gast)


Angehängte Dateien:

Lesenswert?

Ah ok, vielen Dank schonmal. Das macht Sinn.
Gerne poste ich euch das Dateblatt und die Codesegmente für die .ORG

Also einmal für den Start :
1
; ----- program
2
.org    0080h
3
4
main:
5
    reti
6
    call  init
7
    call  get_sw
8
    call  install

hier folgt nun der restliche Code. Ist schon einiges.

Am Ende steht dann noch der Code für den Interrupt :
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

von Daniel V. (danvet)


Lesenswert?

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.

von Daniel V. (danvet)


Lesenswert?

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.

von csol (Gast)


Lesenswert?

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 ?

von Daniel V. (danvet)


Lesenswert?

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...

von csol (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Daniel V. (danvet)


Lesenswert?

Aaalso, im Endeffekt sieht das dann so aus:

>
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
> .org  0ffch
16
>     nop              ; vector 0  nmi
17
>     reti
18
> 
19
>     jp    main          ; reset

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!

von Daniel V. (danvet)


Lesenswert?

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... :-)

von Karl H. (kbuchegg)


Lesenswert?

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
1
.org  0ff0h            ; ***** Interrupt source #4
2
      reti             ; vector 4  timer / adc
3
4
.org  0ff2h            ; ***** Interrupt source #3
5
      jp    irq_arti   ; vector 3  artimer
6
7
.org  0ff4h            ; ***** Interrupt source #2
8
      jp    irq_pc     ; vector 2  port c / spi
9
10
.org  0ff6h            ; ***** Interrupt source #1
11
      reti             ; vector 1  port a / port b
12
13
.org  0ffch            ; ***** Interrupt source #0
14
      reti             ; vector 0  nmi
15
;
16
.org  0ffeh
17
      jp    main       ; reset

von csol (Gast)


Lesenswert?

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.

von Daniel V. (danvet)


Lesenswert?

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...??

von danvet (Gast)


Lesenswert?

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).

von csol (Gast)


Lesenswert?

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 ?

von csol (Gast)


Lesenswert?

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 ?

von Daniel V. (danvet)


Lesenswert?

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-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 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?

von csol (Gast)


Lesenswert?

Ja, sehr. Vielen Dank

von Karl H. (kbuchegg)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.