Warum ist jede Adresse in einem Mikrocontroller nur 8 Bit groß?


18

Ich habe gesehen, dass in einem 32-Bit-Mikrocontroller jede Speicheradresse nur 8 Datenbits enthält. Dies gilt auch für einen 16-Bit-MC. Für 32-Bit-Daten wird eine Kombination von 4 Adressen verwendet. Warum kann eine Adresse keine 32-Bit-Daten direkt speichern (dh 32-Bit- oder 16-Bit-Daten anstelle von 8)?


2
Es hängt vom Datenbus des Microcontrollers ab. Welcher 32-Bit-Mikrocontroller hat Byte-Speicher? Hast du ein Beispiel?
Swanand

4
Einfach nicht wahr, weshalb Programmiersprachen wie C und C ++ die Möglichkeit enthalten, dass ein Byte größer als 8 Bit ist. Es ist nur so, dass die Mehrheit am besten mit 8-Bit-Bytes funktioniert, aber 9-Bit oder 18-Bit sind da draußen.
PlasmaHH

6
Es ist wie Schokoriegel. Sie machen sie immer kleiner für den gleichen Preis.
Olin Lathrop

4
Kann diese Frage umformuliert werden "Warum sind alle Adressen auf 8 Bit ausgerichtet"?
Florian Castellane

2
@FlorianCastellane Dies. Die Adressen sind nicht 8 Bit groß (es sei denn, Sie finden ein Gerät mit <256 Bit Speicher, dann könnten sie es sein).
Jayjay

Antworten:


11

Dies ist praktisch eine Design-Wahl, es gibt keinen triftigen Grund, warum es so sein muss. Früher, als Massenwareprozessoren mit 8-Bit-Werten arbeiteten, war das Mapping konsistenter 1: 1. Aus Gründen der Konsistenz bei der Weiterentwicklung des Designs zu modernen 32- und 64-Bit-Prozessoren war es sinnvoll, die ältere Zuordnung der Byte-Adressierung beizubehalten, obwohl die Datenbusse zunahmen (mit einem sich ändernden Kompromiss zwischen den Implementierungskosten). Einige 32-Bit-MCUs implementieren möglicherweise nur 16-Bit-Datenbusse in einem Speicher, High-End-Prozessoren haben 256 Bit oder mehr und können mehrere Kernregister in einer einzigen Speichertransaktion laden. Breite Schnittstellen eignen sich für Burst- oder Streaming-Vorgänge.

Die kleine adressierbare Speichergröße ist nicht nur für die Verarbeitung von Byte-Werten im Code nützlich, sondern auch für die Arbeit mit Strukturen im Speicher wie Ethernet-Paketen, bei denen bestimmte Bytes gelesen oder geändert werden müssen. Häufig muss diese Art von Operation in der Lage sein, kleine Operationen auszuführen, jedoch sehr effizient.

Es gibt auch Szenarien, in denen mit Big-Endian-, Little-Endian- oder Mixed-Endian-Daten gearbeitet werden muss. Heutzutage gibt es häufig dedizierte Hardwareunterstützung dafür, aber auch hier macht die Byteadressierung des Speichers diese Art von Operation in einigen Szenarien effizienter.

Es ist ziemlich neu, dass die Anzahl der Adreßbits in einem Register ein begrenzender Faktor für den Adreßraum gewesen ist, so dass die Verschwendung von 2 Bits zum Adressieren von Bytes anstelle von 32-Bit-Wörtern vor 10-15 Jahren kein großes Problem gewesen wäre (und jetzt mit 64-Bit-Zeigern (es ist üblich, 48 oder 56 Bit breite Byteadressen zu implementieren). Einführender Informatikunterricht steckt noch ein wenig im Zeitalter der Just-Post-Mainframes fest und spricht die Evolutionsaspekte nicht immer klar an. Unzählige Begriffe wurden verwendet (und definiert), als hochpreisige Architekturen mit geringem Volumen (im Allgemeinen) durch ressourcenbeschränktere und stärker auf Rohstoffe ausgerichtete Prozessordesigns ergänzt wurden.

Ich habe nicht speziell für MCUs geantwortet, die architektonischen Grenzen sind nicht so klar, wie Sie vielleicht annehmen. Selbst ein modernes, von Grund auf neu entwickeltes MCU-Design hat gute Chancen, zusammen mit einem Serverprozessor mit vielen Kernen integriert zu werden oder als einziger Punkt in einem skalierbaren Satz von Produkten zu existieren. In beiden Fällen ist ein konsistenter Ansatz für den Speicherzugriff für den Endbenutzer von Vorteil, der Code schreiben oder portieren muss.

Ich habe eine Frage zur Retrocomputing-SE zu Registergrößen gestellt, um den historischen Aspekten dieser Frage nachzugehen.


2
Ich denke, Prozessoren mit längeren Wortgrößen waren älter als 8-Bit-Prozessoren. Ein 8-Bit-Prozessor wäre ohne ein effizientes Mittel zum Hinzufügen von zwei Multi-Byte-Zahlen ziemlich nutzlos, und frühe Prozessoren könnten Zahlen, die größer als ein einzelnes Maschinenwort sind, nicht effizient verarbeiten.
Supercat

1
Ich habe mit 8-Bit-Prozessoren genug gearbeitet, um zu wissen, dass sie problemlos Multi-Byte-Zahlen hinzufügen können, aber nicht mit einem einzelnen CPU-Befehl. Addieren Sie zunächst die zwei niedrigsten Bytes und erhalten Sie das niedrigste Ergebnisbyte sowie ein separates Übertragsbit. Wenn so viele andere Bytes vorhanden sind, fügen Sie die nächsten Eingangsbytes und das Übertragsbit aus dem vorherigen Schritt hinzu und geben Sie das nächste Ausgangsbyte und das nächste Übertragsbit an. Wenn keine Eingangsbytes mehr vorhanden sind, konvertieren Sie das letzte Übertragsbit in ein weiteres Ausgangsbyte.
User6030

@ user6030: Ist es nicht üblich, einen ADC-Befehl zu haben? AVR funktioniert (ein 8-Bit-RISC-Mikrocontroller , für den gcc ADC verwenden muss, intundlong ), x86 ebenso wie ARM. Ich gehe davon aus, dass die meisten 8-Bit-CPUs noch stärker nachgefragt werden als auf einem System mit breiteren Regs. Oh, sagt Supercat, dass frühen Prozessoren ein effizienter ADC fehlte?
Peter Cordes

Ich denke, es ist ein gültiger Punkt in Bezug auf die Entwicklung der Registergröße (obwohl mir Daten fehlen)
Sean Houlihane

25

Es gibt einige DSPs (z. B. TI C54x), die keine Werte kleiner als 16 Bit adressieren können, und einige Audio-DSPs verwenden 24 Bit. 8-Bit-Werte werden jedoch in so gut wie jedem Universalcode verwendet, sodass sie von allen Universal-CPUs unterstützt werden.

Und nur weil die für Speicheradressen verwendete kleine Einheit 8-Bit-Bytes beträgt, bedeutet dies nicht, dass dies die größte Einheit ist, die tatsächlich auf dem Bus verwendet wird. Die meisten CPUs verwenden ihre native Wortgröße (16/32 Bit) oder sogar eine größere Größe, um den Speicher zu adressieren. Bei Verwendung von Bytezugriffen wird das Byte automatisch aus dem größeren Wort extrahiert.

Beispielsweise verwendet der PCI-Bus immer 32-Bit-Transaktionen, verfügt jedoch über Byte-Aktivierungssignale für den Zugriff, die kleiner sein müssen.


Vielen Dank. Gibt es eine MC, die ein Nibble breit anstelle von Byte im Speicher ist?
Arun Joe Cheriyan

4
Vielleicht der Intel 4004?
pjc50

6
@ArunCheriyan Ein Beispiel für eine CPU, die mit Nibbles als kleinstem adressierbarem Wort arbeitete, ist der Saturn : eine CPU, die HP bereits im letzten Jahrhundert für seine High-End-Taschenrechner entwickelt hat (insbesondere den bekannten HP48). Es hatte eine sehr ungewöhnliche Architektur (64-Bit-Register, 4-Bit-ALU, 20-Bit-Adressen, ...).
dim

Ein weiteres Beispiel: Die kleinste adressierbare Einheit für das TMS320C3x von TI ist 32-Bit.
kkrambo

1
@davidcary Na ja ... Datum und Uhrzeit waren sowieso noch nie meine Stärke. Fragen Sie meine Frau zu ihrem Geburtstag präsentiert, und mein Chef über die Fristen ...
dim

18

Ein 16-Bit- oder 32-Bit-Mikrocontroller muss häufig Daten verarbeiten, die nur 8 Bit (ein Byte) breit sind. Beispielsweise werden Textzeichenfolgen normalerweise mit einem einzelnen Zeichen pro Byte gespeichert. Durch ein Speicheradressierungsschema, mit dem jedes einzelne Byte adressiert werden kann, kann der Mikrocontroller 8 Bit breite Daten effizient verarbeiten. Dies bedeutet, dass sich 32-Bit-Daten normalerweise auf Adressen befinden, die Vielfache von 4 Bytes sind, z. B. 04, 08, 0C usw. Wenn der Speicher jedoch 32 Bit breit ist, kann der Mikrocontroller 32 Bit in einem Lesezyklus lesen . Micro's haben oft Maschinenbefehle, die mit Daten unterschiedlicher Länge arbeiten können. Sie werden also feststellen, dass ein Bewegungsdatenbefehl (MOV) drei Formen haben kann, MOV.B, MOV.W und MOV.L, um 8, 16 und 32 Bits zu bewegen Daten in einer Anweisung.


7

Die grundlegende Antwort lautet "Weil ein Byte so lang ist". Bei einem großen, etablierten Code, der diese Annahme macht, würde das Brechen allerlei Probleme verursachen.

Früher gab es keinen etablierten Code. Prozessoren verwendeten häufig alle Arten von seltsamen Architekturen, wie andere Antworten zeigten. Zu dem Zeitpunkt, als 16-Bit-Prozessoren herauskamen, gab es jedoch genug Code, der davon ausging, dass 8-Bit-Daten verfügbar waren, was eine echte Hürde für die Einführung gewesen wäre, wenn dies nicht einfach gemacht worden wäre.

Ein 32-Bit-Wort pro Adresse hat keinen Nachteil für die Speichergeschwindigkeit. Auf einem 32-Bit-System werden die unteren 2 Adressbits häufig nicht in den Speicher geschrieben. Der Prozessor liest normalerweise das gesamte 32-Bit-Wort und wählt (oder maskiert) das 8-Bit-Byte aus, das er in diesem Wort benötigt. Solange in Ihrem Adressraum genügend Daten gespeichert werden können (bei einem 32-Bit-System auf 2 ^ 32 Byte begrenzt), ist dies kein Problem. Bei vielen 16-Bit- / 32-Bit-Prozessoren dauert die Verarbeitung mit Byte-Werten länger als mit Werten der systemeigenen Wortlänge. Das Lesen eines 32-Bit-Wortes und das Verwerfen eines Teils dieses Wortes erfordert eindeutig einen zusätzlichen Vorgang. im Vergleich nur das 32-Bit-Wort zu lesen.

Umgekehrt, wenn Sie ein System haben , in dem Sie benötigen Speicher effizient nutzen, dann müssen Sie den Zugriff auf die einzelnen Bytes zu können. Wenn Sie nicht können, wird Ihnen der Speicher ausgehen. In diesem Sinne ist es unbedingt erforderlich, auf einzelne Bytes verweisen zu können. Daher ist es sinnvoll, Ihren Speicher in Bytes aufzuteilen.


3
Tatsächlich. Außerdem stellt sich die zusätzliche Frage, ob ein Prozessor die zwei unterschiedlichen Zugriffe verarbeiten kann, die zum automatischen Laden oder Speichern eines nicht ausgerichteten 32-Bit-Werts in der Hardware erforderlich sind , oder ob dies explizit in der Software erfolgen muss.
Chris Stratton

5

Dies wird als byteadressierbarer Speicher bezeichnet. Dies ist normalerweise eine gute Sache, es sei denn, Sie haben nicht genügend Adressraum (z. B. 4 GB mit 32-Bit-Zeigern anstelle von 16 GB mit 32-Bit-Zeigern, bei denen jede Adresse ein separates 32-Bit-Wort ist).


Beachten Sie, dass der Adressraum diese Grenzen überschreiten kann, wenn Sie die Adressen in Teile aufteilen, die jeweils in ein Register passen. Ich hatte einmal einige 8-Bit-Computer, die 64 KB Speicher erreichten, indem sie die Adressen in zwei Teile aufteilten, die in getrennten Registern gespeichert waren, und sah Anzeigen für Computer mit 8-Bit-Prozessoren, die 1 MB Speicher erreichten, indem sie die Adressen in drei Teile aufteilten Teile.
User6030

AVR (8-Bit-RISC-Mikrocontroller) bewirkt Folgendes: Drei Paare der 32 8-Bit-Universalregister können als 16-Bit-Zeiger dereferenziert werden. Es gibt auch eine Möglichkeit, dies mit einem anderen 8-Bit-Segment zu kombinieren, um 24-Bit-Adressen zu erhalten.
Peter Cordes

4

Die 32-Bit-DSPs von Analog Devices Shark haben 32 Bit als kleinste adressierbare Speichereinheit der C-Standard).

Auch Dinge wie int_8, int_16 und so sind nicht in definiert, eine böse Überraschung, wenn Code von anderen Plattformen portiert wird.


1

Die Größe der adressierbaren Speichereinheit ist im Wesentlichen ein Kompromiss zwischen der adressierbaren Speicherkapazität und der verschwendeten Speicherkapazität.

Adressierbarer Speicher . Stellen Sie sich eine 32-Bit-CPU vor: Wenn Sie Bytes adressieren, können Sie bis zu 4 GB Speicher adressieren. Wenn Sie einzelne Bits adressieren, wird diese Menge auf 512 MB reduziert, und wenn Sie 32-Bit-Wörter adressieren, haben Sie 16 GB. (Ihre Frage scheint letzteres nahezulegen).

Speicher verschwendet . Wenn Sie eine Variable haben, die mit X-Bits dargestellt werden kann, und Sie können nur Einheiten von N Bits dafür zuweisen, werden Sie durchschnittlich (N-1) / 2 Bits verschwenden, vorausgesetzt, X> N. Wenn Sie einzelne Bits adressieren Verwenden Sie den Speicher mit 100% Effizienz (zumindest aus Sicht der Adressierung). Mit Bytes verschwenden Sie 3,5 Bit pro Variable (56% Effizienz) und mit 32-Bit-Wörtern 15,5 Bit (52% Effizienz). Aber es wird schlimmer: Wenn die meisten Variablen klein sind (z. B. Zeichen, Boolesche Werte, Statusflags), verschwenden Sie den größten Teil des Speichers, wenn Ihre adressierbaren Einheiten zu groß sind.

Angenommen, die durchschnittliche Größe einer Variablen beträgt 8 Bit.

  • Auf einem bitadressierbaren Computer können Sie die Zuweisung mit einer Effizienz von 100% durchführen, wodurch Sie 512*1024*1024*100%= 0,54 Milliarden Variablen erhalten.
  • Auf einem byteadressierbaren Computer werden Sie eine Zuweisung mit einer Effizienz von 56% vornehmen, wodurch Sie 4096*1024*1024*56%= 2,4 Milliarden Variablen erhalten. Das ist fast das Fünffache eines bitadressierbaren Computers! Natürlich müssen Sie 8-mal mehr Speicher kaufen.
  • Da auf einem 32-Bit-adressierbaren Computer mindestens die Hälfte Ihrer Variablen weniger als 8 Bit belegt, werden sie mit einer Effizienz von weniger als 7% zugewiesen (unter Verwendung von 4,5 von 32 Bit). Auf jeden Fall erhalten Sie nicht mehr als 4,3 Milliarden Variablen (da Sie nur so viele unterschiedliche Adressen haben) und weniger als die in der Realität. Wenn Sie komplexe Berechnungen vermeiden, erhalten Sie vermutlich 20 bis 30% mehr Speicherplatz als ein Computer mit Byte-Adressierung, während Sie das Vierfache des RAM-Preises bezahlen.

1

Vermutlich schon in den anderen Antworten verschiedene Möglichkeiten genannt. Im Allgemeinen besteht ein Byte heute, aber nicht unbedingt historisch, aus 8 Bits. Die meiste Zeit beschäftigen wir uns mit "byteadressierbarem Speicher", was bedeutet, dass das KLEINSTE, auf das wir mit einer einzelnen Adresse zugreifen können, ein Byte ist. Das heißt aber nicht, dass wir NUR darauf eingehen können. Abhängig von der Plattform kann eine einzelne Adresse verwendet werden, um auf ein Byte, ein Halbwort / Wort (16 Bit), ein Wort / Doppelwort (32 Bit) usw. zuzugreifen. Der Befehl bestimmt im Grunde genommen, wie groß der gewünschte Zugriff ist (8, 16, 32, 64 usw.), normalerweise in diesen Einheiten 8, 16, 32, 64. Aber das ist nicht hart und schnell, "es kommt darauf an".

Abhängig vom Design des Prozessors und / oder des Systems gibt es auch keinen Grund anzunehmen, dass die Größe des Zugriffs der Größe des Speichers oder der Größe des kleinsten Zugriffs entspricht. Bei immer größeren Anforderungen ist es im Laufe der Zeit immer weniger sinnvoll, das Speichersystem tatsächlich mit der kleinsten Größe zu implementieren. Der Computer, auf dem Sie dies lesen, verwendet wahrscheinlich einen 32-Bit-breiten Datenbus oder einen 64-Bit-breiten Datenbus für alle Zugriffe Wenn Sie ein Byte lesen möchten, führt es einen 64-Bit-Lesevorgang durch und wirft den Rest der Bits weg. Warum kostet es nichts mehr? Halten Sie den Bus so weit wie möglich in der Nähe des Prozessorkerns, und der Prozessor wählt die richtige Byte-Spur aus. kostet mehr Logik und oder Takte, um den Bus enger zu machen oder die Bytes in den Bytespuren zu verschieben (wird manchmal ausgeführt). Interne RAMs in einem Mikrocontroller können beispielsweise 32 Bit breit sein, wenn dies für das System sinnvoll ist. könnte 16 sein. Ja, für Schreibvorgänge, die Sie mehr Zyklen brennen, müssen Sie irgendwo entlang der Linie lesen, ändern und schreiben. Möchten Sie ein einzelnes Byte auf Ihren PC schreiben, passiert irgendwo ein 64-Bit-Lesevorgang, und irgendwo wird dann ein Byte dieser 64-Bit-Lesevorgänge geändert. Dies hängt davon ab, was Sie danach tun. Danach werden 64-Bit-Lesevorgänge möglicherweise mit nur diesen 8-Bit-Lesevorgängen wiederhergestellt Anders als zuvor, machen Caching und Ihr Code dies jedoch nicht zu einer generischen Regel. Schreibvorgänge sind jedoch Feuer und Vergessen. Der Speichercontroller kann die Adresse und die Daten vom Prozessor abrufen und dem Prozessor ermöglichen, weiterzulaufen, während er schließlich die schreibsparen- den Uhren ausführt, möglicherweise mehr Uhren, die beim Lesen, Ändern und Schreiben gebrannt werden (falls erforderlich) bereits im Cache),

Es gibt auch heute noch Ausnahmen zu so ziemlich allem, es gibt vielleicht Anweisungen oder Zugriffstypen in einigen Systemen, die bitadressierbar sind, es gibt einige Systeme, in denen die Adresse in Einheiten von etwas anderem als einem Byte angegeben ist. Ein Byte war nicht immer 8 Bit und vielleicht gibt es noch Systeme, auf denen dies zutrifft (früher verwendeten wir Oktal, und ein Wort mit 9 Bit und 18 oder 36 Bit ist für menschliche Programmierer und Chipdesigner, die an Oktal denken, sehr sinnvoll) 8 Bit ist für Hexadezimaldenker sehr sinnvoll.

Auf dem Computer, auf dem Sie dies lesen, besteht das eigentliche Dram-Modul wahrscheinlich aus mehreren 8 Bit breiten Teilen, die Sie leicht sehen können, obwohl der Datenbus für diesen Dram-Controller möglicherweise 32 oder 64 Bit breit ist. Wenn es 8 oder 9 Chips auf einer Seite hat, ist es wahrscheinlich ein 64-Bit- oder 72-Bit-Bus (64-Bit plus 8-Bit-ECC), der mit 8-Bit-breiten Teilen implementiert ist. Wenn Sie 4 oder 5 Chips auf einer Seite des Moduls haben, aber immer noch Tonnen von Pins haben, dann ist es entweder 32 Bit breit (heutzutage unwahrscheinlich) oder 4 der Chips sind 16 Bit breit und wenn es einen fünften gibt, kann es sein 16 Bit breit sein und nur 8 verwendet werden oder es ist ein 8 Bit breiter Teil. Es gibt auch 32-Bit-Teile, aber am häufigsten sind 8-Bit-Teile. Eine sehr verbreitete Praxis, die weit zurückreicht.

Wir müssten wissen, welcher Mikrocontroller. Da Sie 32 Bit erwähnen, ist es sehr wahrscheinlich (ohne detaillierte Informationen, die wir jedoch nicht sagen können), dass der Speicher in diesem Teil 32 Bit breit ist und alle Zugriffe auf ihn 32 Bit breit sind. Die Anweisungen würden wahrscheinlich bestimmen, was das Programm will, das wahrscheinlich einen 8-Bit-, 16-Bit- und 32-Bit-Zugriffstyp anbietet. Die kleineren Befehle für Schreibvorgänge würden irgendwo einen Lese-Änderungs-Schreibvorgang erfordern. Lesen Sie einfach, indem Sie die Byte-Spuren ignorieren. Gleiches gilt für den Flash, auch wenn Flash-Schreibvorgänge ein anderes Thema sind. Der interne Flash ist jedoch höchstwahrscheinlich 32 Bit breit und alle Lesevorgänge erfolgen in Einheiten von 32 Bit. Ein externer Blitz, das ist eine andere Geschichte, höchstwahrscheinlich sind sie ein Bit breit (SPI oder i2C), obwohl SPI-Teile manchmal 1, 2 oder 4 Bits unterstützen können, aber ein Miso-Pin ist am häufigsten. Intern sind sie in Einheiten von Bytes organisiert, 8 Bit breit oder 16 oder 32, oder wer weiß, Sie verschieben und adressieren sie in Einheiten von Bytes. Mit SPI können Sie in einer einzigen Transaktion zwischen einem Byte und dem gesamten Speicher wechseln. Dies hängt vom Design des Flash-Teils ab.


0

Sie können auch 1-Bit-Prozessoren erhalten!

Die Datenbreite folgt der Registerbreite (Akkubreite). Dies ist normalerweise die "Prozessorbreite", während der Adressbus unterschiedlich sein kann (normalerweise breiter), aber technisch je nach Verwendung schmaler sein kann.

8 ist natürlich eine Potenz von zwei Zahlen. Wir haben Geschichte zu verdanken für die allgegenwärtige Verwendung von 8-Bit- und COST / Fähigkeit der Technologie. Lange Zeit herrschten 8 Bit, ein Grund dafür war die Breite der Busse und die Schwierigkeit, Register (und RAM) breiter als 8 Bit zu machen (kein Punkt bei 16-Bit-Daten, wenn Ihre Register alle 8 Bit sind). 8 Bits sind ziemlich geschickt und in Hex sehr sinnvoll. 8 Bits können Ihr Alphabet, Zahlen, Zeichen und Steuerzeichen (ASCII) oder 0 bis 255 oder + -127 enthalten. Der Zugriff auf mehr als 256 Datenbytes (8-Bit-Adressbus) ist mit Paging einfach. Wählen Sie die Seite und dann das Byte aus, z 256 Seiten von 256 bringen Sie auf 64 KB (65536). Normalerweise ist Seite Null ein Notizblock, da der Zugriff schneller erfolgt, da hierfür keine Seite eingerichtet werden muss. Mein erster Computer hatte 1k x 8bits statischen RAM! (dynamischer RAM war billiger, aber brauchte mehr Hardware, um es zu aktualisieren). Mit ein paar Flags (c, nc, z, nz), Addieren, Subtrahieren, Drehen nach links und rechts können Sie auf einer 8-Bit-Maschine ziemlich komplexe Berechnungen durchführen. Sie brauchen keine Gleitkomma-Recheneinheit! Nicht super schnell, aber machbar! Viele frühe Prozessoren konnten in einem Schritt betrieben werden, und die Verwendung von einfachem statischem RAM machte das Debuggen sehr einfach. Wenn Sie einige Oktalpuffer und frühe rote LEDs hinzufügen, können Sie beobachten, wie sich die Adressen- und Datenbusse ändern :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.