Forum: Mikrocontroller und Digitale Elektronik Takte zählen in asm


von deddi1999 (Gast)


Lesenswert?

hallo, ich verstehe etwas nicht und bräuchte Hilfe…

Aufbau:
zwei Board Arduino uno, verbunden mit GND, und PIN8 ( bit0 PORTB )
einer sendet eine 0 auf pin 8, der andere empfängt sie
nun zähle ich auf beiden Seiten die Schleifendurchläufe ( 2 x 8 bit ) 
und bekomme extrem unterschiedliche Werte heraus :
Sender äussere 150, innere 250
Empf.  äussere 146, innere 145

die Schleifen sind doch identisch programmiert ?  ich verstehe das 
gerade nicht mehr….

hier Sender:
1
void loop(){
2
  
3
  asm volatile (
4
    "reset:                              \n\t"      
5
    "       sbis   %[lese],    0         \n\t"
6
    "       rjmp   reset                 \n\t" 
7
    "       cli                          \n\t" 
8
    "       sbi    %[portdir], 0         \n\t"
9
    "       cbi    %[port],    0         \n\t"
10
    "       ldi    r17,        150       \n\t"
11
    "lp2:   ldi    r16,        250       \n\t"
12
    "lp1:   sbic   %[lese] , 0           \n\t"
13
    "       rjmp   fertig                \n\t" 
14
    "       dec    r16                   \n\t"
15
    "       brne   lp1                   \n\t"
16
    "       dec    r17                   \n\t"
17
    "       brne   lp2                   \n\t"  
18
    "fertig:                             \n\t"  
19
    "       sbi    %[port],    0         \n\t"
20
    "       cbi    %[portdir], 0         \n\t"
21
    "       sbi    %[port],    0         \n\t"
22
    "       sei                          \n\t"
23
    "end:                                \n\t"
24
    
25
    : [antwort] "+r" (aa)
26
    : [portdir] "I" (_SFR_IO_ADDR(DDRB)), 
27
      [port]    "I" (_SFR_IO_ADDR(PORTB)),
28
      [lese]    "I" (_SFR_IO_ADDR(PINB))
29
      
30
    :"r16", "r17", "r18"
31
 );
32
     
33
  //Serial.println(aa); 
34
        
35
  delay(2500);
36
}

hier Empfänger:
1
void loop(){
2
   
3
  asm volatile (
4
    
5
    "warte:                              \n\t"      
6
    "       sbic   %[lese],    0         \n\t"
7
    "       rjmp   warte                 \n\t"  
8
    "       cli                          \n\t"   
9
    "       ldi    %1,         0         \n\t"
10
    "lp2:   ldi    %2,         0         \n\t"
11
    "lp1:   sbic   %[lese],    0         \n\t"
12
    "       rjmp   fertig                \n\t"      
13
    "       inc    %2                    \n\t"
14
    "       brne   lp1                   \n\t"
15
    "       inc    %1                    \n\t"
16
    "       brne   lp2                   \n\t" 
17
    "fertig:                             \n\t"
18
    "       sei                          \n\t"
19
     
20
    : "+r" (aa), "+r" (bb), "+r" (cc)
21
    : [portdir] "I" (_SFR_IO_ADDR(DDRB)), 
22
      [port]    "I" (_SFR_IO_ADDR(PORTB)),
23
      [lese]    "I" (_SFR_IO_ADDR(PINB))      
24
    : 
25
   );
26
     
27
  //Serial.println(aa); 
28
  Serial.println(bb); 
29
  Serial.println(cc); 
30
  Serial.println(); 
31
  
32
        
33
  
34
}

von c-hater (Gast)


Lesenswert?

deddi1999 schrieb:

> bekomme extrem unterschiedliche Werte heraus :
> Sender äussere 150, innere 250
> Empf.  äussere 146, innere 145
>
> die Schleifen sind doch identisch programmiert ?

Nein, sind sie nicht. Sie haben nur die gleiche Struktur, sind aber 
nicht identisch.


>     "       ldi    r17,        150       \n\t"
>     "lp2:   ldi    r16,        250       \n\t"

vs.

>     "       ldi    %1,         0         \n\t"
>     "lp2:   ldi    %2,         0         \n\t"


Wie blind muß man sein, um DIESEN Unterschied in den paar Zeilen 
NICHT zu sehen? Dazu muß man noch nicht mal Ahnung von Assembler 
haben, sondern einfach nur sorgfältig genug vergleichen.

Und ganz sicher kann das nicht passieren, wenn man VERSTEHT, was diese 
Delay-Routine macht, denn dann schaut man ganz automatisch als 
allererstes an genau die Stelle, wo die Zähler-Register initialisiert 
werden...

von deddi1999 (Gast)


Lesenswert?

hallo,

danke für die Antwort - eine Beleidigung wäre jedoch nicht nötig gewesen 
- aber dennoch, wenn ich die Register direkt anspreche, und die Werte 
nach den Schleifen zurück schreibe, dann ändert sich nichts !!

was also ist das ?
1
void loop(){
2
   
3
  asm volatile (
4
    
5
    "warte:                              \n\t"      
6
    "       sbic   %[lese],    0         \n\t"
7
    "       rjmp   warte                 \n\t"  
8
    "       cli                          \n\t"   
9
    "       ldi    r17,         0         \n\t"
10
    "lp2:   ldi    r16,         0         \n\t"
11
    "lp1:   sbic   %[lese],     0         \n\t"
12
    "       rjmp   fertig                \n\t"      
13
    "       inc    r16                    \n\t"
14
    "       brne   lp1                   \n\t"
15
    "       inc    17                    \n\t"
16
    "       brne   lp2                   \n\t" 
17
    "fertig:                             \n\t"
18
    "       sei                          \n\t"
19
    "       mov    %1, r17                \n\t"
20
    "       mov    %2, r16                  \n\t"
21
     
22
    : "+r" (aa), "+r" (bb), "+r" (cc)
23
    : [portdir] "I" (_SFR_IO_ADDR(DDRB)), 
24
      [port]    "I" (_SFR_IO_ADDR(PORTB)),
25
      [lese]    "I" (_SFR_IO_ADDR(PINB))      
26
    : 
27
   );
28
     
29
  //Serial.println(aa); 
30
  Serial.println(bb); 
31
  Serial.println(cc); 
32
  Serial.println(); 
33
  
34
    
35
  
36
}

von Karl H. (kbuchegg)


Lesenswert?

deddi1999 schrieb:

> nun zähle ich auf beiden Seiten die Schleifendurchläufe ( 2 x 8 bit )
> und bekomme extrem unterschiedliche Werte heraus :
> Sender äussere 150, innere 250
> Empf.  äussere 146, innere 145


Was soll denn da extrem unterschiedlich sein.

Der Sender macht 150*250 + 250 = 37750 Durchgänge
Der Empfänger macht 146*256 + 145 = 37521 Durchgänge

Extrem sieht bei mir anders aus.

von c-hater (Gast)


Lesenswert?

Karl Heinz schrieb:

> Was soll denn da extrem unterschiedlich sein.
>
> Der Sender macht 150*250 + 250 = 37750 Durchgänge
> Der Empfänger macht 146*256 + 145 = 37521 Durchgänge
>
> Extrem sieht bei mir anders aus.

Ja, weil du nicht wirklich rechnen kannst. Tatsächlich ist der 
Unterschied in etwa in der Größenordnung 150*250=37500 vs. 256*256=65536 
Durchläufe der inneren Schleife.

Die genauere Analyse spare ich mir hier mal, weil die Durchläufe der 
inneren Schleife in diesem Fall wirklich überaus signifikant sind. Die 
Einbeziehung der äußeren Schleife macht die Unterschiede nur noch 
geringfügig (nämlich um genau 318 Takte) extremer.

Mein Rat an dich: Bleib' bei Sachen, von denen du etwas verstehst. 
Selbst so absolut trivialen Asm-Scheiß wie eine simple Warteschleife 
kannst du jedenfalls offensichtlich nicht korrekt analysieren.

Und mein Rat an den OP: Es steht dir definitiv nicht zu, dich über 
angebliche Beleidigungen zu beschweren, denn das Aussprechen eines 
offensichtlich wahren Sachverhaltes ist keine Beleidigung, sondern 
allenfalls unhöflich. Nun, ich wollte auch nicht höflich sein, nur 
sachlich hilfreich...

von deddi1999 (Gast)


Lesenswert?

danke Karl Heinz,

danke für die Antwort! Ich beginne gerade mit Assembler und saß da nicht 
richtig herum auf dem Pferd. Meine Annahme, es kämen identische Zahlen 
heraus war natürlich Schwachsinn ;-)

In der Zwischenzeit habe ich auch die Boards getauscht und hier kommen 
auch  Unterschiede zum Vorschein, Die Taktfrequenzen weichen ja sicher 
auch voneinander ab ( wieviel weiß ich jetzt nicht ).

also nochmals danke

von deddi1999 (Gast)


Lesenswert?

ach ja - bevor ich es noch vergesse…

danke c-hater für deine Antwort,

zu diesem Kommentar brauche ich nichts mehr zu sagen - du hast dich hier 
überdeutlich von deiner besten, menschlichen Seite gezeigt.

Ich finde es nur schade, das ganze Foren in Verruf geraten, nur weil 
sich Einzelpersonen bisweilen nicht unter Kontrolle haben.

Das, was du an "Durchblick" in Fragen der Programmierung hast oder zu 
haben glaubst, das scheint dir an anderer, zwischenmenschlicher Stelle 
definitiv zu fehlen. Das Universum schafft doch immer wieder einen 
Ausgleich!

nun denn - sei's drum ….

Ich lasse mir hier sicher nicht von dir den Mund verbieten und auch 
nicht den Spaß an MIC oder Programmierung verderben.

Auch zukünftig werde ich Fragen stellen - und wenn sie dir dumm 
erscheinen, kümmere dich einfach nicht mehr darum - bitte !!!!

von Karl H. (kbuchegg)


Lesenswert?

Jetzt seh ichs erst.
Bei deine Sendercode werden die Register decrementiert, bei deinem 
Empfängercode werden sie hingegen incrementiert.

D.h. die Ergebniszahlen sind nicht so einfach vergleichbar. Die müsste 
man erst mal entsprechend umrechnen. Kann man natürlich machen, ist aber 
auf längere Sicht fehleranfällig.

Vorschlag: bring erst mal beide auf wirklich die identische Struktur, 
beide zb mit Increment, beide zb bei 0 beginnend zu zählen. Und dann 
vergleich nochmal die Zahlen.

> Auch zukünftig werde ich Fragen stellen ...

Ignorier ihn einfach. Ausser C-Bashing trägt er selten irgendwas 
sinnvolles in einem Thread bei.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Karl Heinz schrieb:
> Der Sender macht 150*250 + 250 = 37750 Durchgänge
> Der Empfänger macht 146*256 + 145 = 37521 Durchgänge

Wie kommst du auf die +250 im ersten Fall? Ich hätte einfach
150*250=37500 gerechnet. Die beiden Werte unterscheiden sich dann nur
noch um 21 innere Schleifendurchläufe oder etwa 500ppm.

@deddi1999:

Vergiss die Kommentare von c-hater. Er hat deinen Assemblercode nicht
einmal ansatzweise verstanden.

@c-hater:

> Mein Rat an dich: Bleib' bei Sachen, von denen du etwas verstehst.
> Selbst so absolut trivialen Asm-Scheiß wie eine simple Warteschleife
> kannst du jedenfalls offensichtlich nicht korrekt analysieren.

von deddi1999 (Gast)


Lesenswert?

hallo Karl Heinz,

o.k. ignorieren - das geht gut….

habe die slave-routine umgeschrieben, Anfangswerte auf 255 gesetzt und 
die beiden inc in dec getauscht,

folgendes Ergebnis:  außen 108, innen 220, also

255-108 = 147
255-220 = 35

147*256+35 = 37667 Durchläufe, zu 37750…. das ist schon besser

sind nicht für den dec und inc je ein Takt nötig, wie kann das dann 
anders ausfallen habe ich wohl noch nicht richtig verstanden?

nun denn, im Sender habe ich 14,203ms und im Empfänger 14,171ms wenn ich 
die benötigten Taktzyklen bei 16MHz berücksichtige. Und wie bereits oben 
erwähnt ändert sich das Ergebnis um ca. 40 Durchläufe ( 14,047 ms ) wenn 
ich die Hardware vertausche. Das liegt mit einer Abweichung von ca. 0,8% 
im Toleranzbereich der Quarze.

Wie das wohl ausgeht, wenn beide Boards mit dem selben Takt laufen …. 
das probier ich mal aus - demnächst

Was ist mit der Verzweigung sbic, im Handbuch steht, benötigte Takte 
3/2/1
3 bei skip, 1 bei rjmp und 2 bei ….?

Danke Detmar

von deddi1999 (Gast)


Lesenswert?

ok.

ich noch mal

in dem Berechnungsbeispiel hatte ich die Anfangswerte auf 255 für die 
Schleifen gesetzt. Dann sollte ich den Anzahl der Durchläufe auch so 
berechnen:

147 * 255 + 35 = 37520

das macht dann 14,12 ms im Empfänger


Yalu X.
"Wie kommst du auf die +250 im ersten Fall? Ich hätte einfach
 150*250=37500 gerechnet. Die beiden Werte unterscheiden sich dann nur
 noch um 21 innere Schleifendurchläufe oder etwa 500ppm."

150 * 250 = 37500 war auch mein erster Berechnungsansatz für den Sender!

das wären dann 14,11ms !!! echt o.k.

Ich hatte nur in der Interpretation der Empfängerwerte den Bug, dass die 
innere Schleife ja bei jedem Durchlauf der Äußeren 256 x durchläuft ( 
Danke Karl Heinz )

wenn man zu lange auf eine Aufgabe schaut, dann verschwimmt die Wahrheit 
enorm…

ich mach erstmal 'ne kleine Pause...

Danke an Euch !

von c-hater (Gast)


Lesenswert?

Karl Heinz schrieb:

> Ignorier ihn einfach. Ausser C-Bashing trägt er selten irgendwas
> sinnvolles in einem Thread bei.

Ja, fast immer genau so wie in diesem Fall hier... Da lieferte doch 
wirklich nur ich (als einziger) eine korrekte Analyse des Zeitverhaltens 
der geposteten Routinen...

Sowas ördinäres wie zutreffende Fakten können aber natürlich unmöglich 
als sinnvoller Beitrag zum Thread gewertet werden. Sagen jedenfalls 
übereinstimmend alle c-hater-Hater im Thread...

von Karl H. (kbuchegg)


Lesenswert?

Yalu X. schrieb:
> Karl Heinz schrieb:
>> Der Sender macht 150*250 + 250 = 37750 Durchgänge
>> Der Empfänger macht 146*256 + 145 = 37521 Durchgänge
>
> Wie kommst du auf die +250 im ersten Fall?

Weil ich nicht aufgepasst habe. Die beiden Routinen unterscheiden sich 
dann doch fundemantal durch mehr als nur 2 Zahlenwerte.

von Cyblord -. (cyblord)


Lesenswert?

Karl Heinz schrieb:
>> Auch zukünftig werde ich Fragen stellen ...
>
> Ignorier ihn einfach. Ausser C-Bashing trägt er selten irgendwas
> sinnvolles in einem Thread bei.

Nun aber hier war er der einzige der die korrekte Lösung hatte. Und du 
hast dich getäuscht. Das kann man auch einfach mal einräumen und dabei 
den Autor der es besser wusste, NICHT gleichzeitig diffamieren.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Cyblord ---- schrieb:
> Nun aber hier war er der einzige der die korrekte Lösung hatte.

Aber auch nur teilweise.

c-hater schrieb:
> Unterschied in etwa in der Größenordnung 150*250=37500 vs. 256*256=65536

Der zweite Wert (für den Empfänger) ist völlig daneben, weil der c-hater
von der falschen Abbruchbedingung ausgegangen ist (es gibt ja zwei
Ausstiegspunkte aus der Schleife).

Karl Heinz schrieb:
> Der Sender macht 150*250 + 250 = 37750 Durchgänge
> Der Empfänger macht 146*256 + 145 = 37521 Durchgänge

Karl Heinz hingegen hat den zweiten Wert richtig bestimmt und sich
lediglich beim ersten um 250 vertan. Trotzdem konnte er zeigen, dass die
Beobachtung von deddi1999 plausibel ist, und darum ging es ja in der
Anfrage. Der c-hater konnte dies nicht, weil seine Ergebnisse auf Grund
seines Fehlers viel zu weit voneinander abwichen.

Einen Fehler zu machen ist ja auch kein Problem (jedem passiert das hin
und wieder), den eigenen Fehler nicht zu erkennen und stattdessen andere
Leute niederzumachen aber schon. Karl Heinz hat seinen kleinen Fehler
eingesehen, der c-hater seinen großen aber immer noch nicht.

von deddi1999 (Gast)


Lesenswert?

hallo,

welche Spielchen hier so alles gespielt werden, das soll mich nicht 
interessieren ...

Ich finde es nur schade, dass das eigentliche Thema in diesem Forum 
dabei vollkommen zur Nebensache verkommt. Es wird extrem viel Zeit 
vergeudet.

  Belehrungen - Überheblichkeit - Hybris - Zynismus - Machtkämpfe - 
u.v.m.

Diese Eigenschaften gehören hier nicht her.

Der Hinweis von Karl Heinz hat mich wieder auf die Spur gebracht - der 
Rest scheint zwar trivial - doch selbst hier sind eben auch Fehler 
möglich.

Also - danke an jeden, der sich hier Gedanken gemacht hat!!

Detmar

von c-hater (Gast)


Lesenswert?

Yalu X. schrieb:

> Der zweite Wert (für den Empfänger) ist völlig daneben, weil der c-hater
> von der falschen Abbruchbedingung ausgegangen ist (es gibt ja zwei
> Ausstiegspunkte aus der Schleife).

OMG. Du bist ja noch schlimmer als Karl Heinz. Der duckt sich nur weg 
(wahrscheinlich hat er begriffen, daß er im Unrecht war). Du hingegen 
beharrst bemerkenswert störrisch auf deiner falschen Meinung. So 
störrisch, daß ich mich genötigt sehe, auch dich noch zu demontieren...

Na klar gibt es zwei Abbruchbedingungen, soweit stimmt dein Gesülze 
immerhin.

Bezieht man aber die zweite ein, nämlich den Zustand des einen Bits, 
welches nicht in der Schleife selber geändert wird, sondern nur in Folge 
eines äußeren Einflusses, dann wird schon die Frage völlig sinnlos, dann 
könnte man nämlich keinerlei definierte Laufzeit für die Routine 
insgesamt oder für die Durchlaufzahlen der Schleifen mehr angeben. Es 
wäre dann allenfalls noch möglich, eine minimale und maximale 
"Antwortzeit" vom Eintritt des äußeren Ereignisses bis zum Verlassen der 
Schleife anzugeben. OK, mit ein wenig Tricksen könnte man sogar die 
verstrichene Zeit zwischen Eintritt in die Routine und dem von außen 
erzwungenen Verlassen selbiger aufzeichnen/messen, aber das gibt der 
Code im OP nicht her.

Was nun die Antwortzeiten betrifft: Da die Abfrage des Bits in der 
inneren Schleife erfolgt und die Struktur des Codes gleich ist, gibt es 
hier keinen Unterschied zwischen Sender und Empfänger. Die minimale 
Antwortzeit wären drei Takte (einer für das sbic mit Ergebnis "nicht 
verzweigen" und zwei für den rjmp). Die maximale Antwortzeit würde dem 
hinzufügen:
1. (fast) einen Takt für die Synchronisierung des Port-Read
2. einen vollen Durchlauf der inneren Schleife mit dem Ergebnis beim
   inneren "brne", das sie gerade durchlaufen wurde (4 Takte)
3. einen Durchlauf der äußeren Schleife bis zum "sbic" zuzüglich dem, 
was
   auch bei der minimalen Antwortzeit passiert. Also weitere 7 Takte.
Die maximale Antwortzeit beträgt also 7+4+1=12 Takte.

Oder anders ausgedrückt: Minimal-Latenz (knapp über) 3 Takte, Jitter 9 
Takte.

Eigentlich Trivialst-Scheiß, für viele C-ler aber scheinbar völlig 
unbegreifbarer Zauberkram. Immerhin scheint es aber noch welche zu 
geben, die zumindest soweit durchblicken, dass sie erkennen können, was 
richtig ist und sich auch nicht scheuen, das auch dann noch 
auszusprechen, nachdem die mächtigen, schwer C-lastigen Moderatoren ihre 
objektiv falsche Sicht der Dinge dargestellt haben...

Danke "cyblord". Ich weiß, daß du voll auf C abfährst und ich dich 
deshalb niemals wirklich verstehen werde. Aber ich nehme (zum 
wiederholten Male) wohlwollend zur Kenntnis, dass deine Kompetenz sich 
nicht auf C alleine beschränkt. Solche C-User mag ich, denn ich bin 
selber so einer...

Allerdings geht mir deine Begeisterung für diese Sprache völlig ab. Du 
nutzt sie, wann immer du kannst, ich nur dann, wann immer ich es nicht 
vermeiden kann...

von Yalu X. (yalu) (Moderator)


Lesenswert?

c-hater schrieb:
> OMG. Du bist ja noch schlimmer als Karl Heinz.

Ach komm, jetzt stell dich nicht so an. Das ist nun wirklich nicht so
schwer zu kapieren, vor allem, wenn man bereits die entsprechenden
Hinweise erhalten hat.

c-hater schrieb:
> Na klar gibt es zwei Abbruchbedingungen

Schön, das du das inzwischen auch erkannt hast.

> Bezieht man aber die zweite ein, nämlich den Zustand des einen Bits,
> welches nicht in der Schleife selber geändert wird, sondern nur in Folge
> eines äußeren Einflusses, dann wird schon die Frage völlig sinnlos, dann
> könnte man nämlich keinerlei definierte Laufzeit für die Routine
> insgesamt oder für die Durchlaufzahlen der Schleifen mehr angeben.

Nicht hundertprozentig exakt, aber genau genug, um entscheiden zu
können, ob die vom TE angegebenen Schleifenzahlen plausibel sind oder
nicht.

Und ja, sie sind plausibel.

Nach deinen Ausführungen hingegen wären sie nicht plausibel. Das liegt
ganz einfach daran, dass du fälschlicherweise davon ausgehst, dass auf
Empfänger die Schleifen bis zum Ende ausgeführt werden. Dabei geht aus
dem Eröffnungsbeitrag und dem geposteten Code klar hervor, wann das
Signal auf PB0 die Schleife abbricht, nämlich nachdem der Sender seine
150·250=37500 Schleifendurchläufe durchgenudelt hat und die PB0-Leitung
auf high setzt.

Da ein Schleifendurchlauf beim Empfänger etwa gleich lang¹ dauert wie
beim Sender, ist hier etwa die gleiche Anzahl von Schleifendurchläufen
zu erwarten. Allein schon deswegen kann die von dir genannte Zahl 65536
nicht stimmen.

Die tatsächliche Zahl lässt sich leicht aus den Angaben des TE

> Empf.  äussere 146, innere 145

berechnen. Dabei ist zu berücksichtigen, dass sich die zweite Zahl (145)
nur auf den letzten äußeren Schleifendurchlauf bezieht. In den 146
vorangehenden äußeren Schleifendurchläufen zählt die innere Schleife
jeweils von 0 bis 255. Das alles geht übrigens aus dem geposteten Code
klar hervor.

Somit ist die Gesamtzahl der Schleifendurchläufe auf Empfängerseite
146·256+145=37521, was ziemlich gut mit der Senderseite übereinstimmt.

Damit ist die scheinbare Diskrepanz zwischen

> Sender äussere 150, innere 250

und

> Empf.  äussere 146, innere 145

geklärt und das Problem des TE gelöst.

Die von dir ermittelten 65536 Schleifendurchläufe sind hier völlig
irrelevant, da die Schleife normalerweise nie komplett bis zum Ende
ausgeführt wird. Das passiert höchstens dann, wenn der Sender ausfällt
und nicht mehr in der Lage ist, die PB0-Leitung am Ende seiner
Warteschleife auf high zu setzen. Wäre diese Fall tatsächlich
eingetreten, wären die vom TE ermittelten Schleifendurchläufe nicht

> Empf.  äussere 146, innere 145

sondern

> Empf.  äussere 256, innere 256

gewesen.

———————————
¹) Wegen eines möglichen Unterschieds der Taktfrequenzen von Sender und
   Empfänger kann diese Zeitdauer etwas abweichen.

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.