Wenn ein 32- Bit-Prozessor ungefähr 4 GiB RAM (dh ) Bytes verarbeiten kann, warum verfügt mein Arduino Mega 2560 über 8 KiB SRAM, wenn er als 8- Bit-Prozessor nur 256 Bytes verarbeiten kann Bytes ( )? Oder lese ich die folgende Seite falsch?
Wenn ein 32- Bit-Prozessor ungefähr 4 GiB RAM (dh ) Bytes verarbeiten kann, warum verfügt mein Arduino Mega 2560 über 8 KiB SRAM, wenn er als 8- Bit-Prozessor nur 256 Bytes verarbeiten kann Bytes ( )? Oder lese ich die folgende Seite falsch?
Antworten:
Die meisten 8-Bit-CPUs haben 16-Bit-Adressbusse, mit denen sie 64 KB adressieren können, gerade weil 256 Byte wirklich nicht ausreichen, um viel zu tun! Es bedeutet nur, dass sie zwei Bytes anstatt eines laden müssen, jedes Mal, wenn sie eine Adresse laden müssen. Etwas langsamer, aber in Anbetracht ihrer Größe erträglich.
(Und ja, es gibt viele Ausnahmen, die meistens entstanden sind, als 64k zu klein wurde, aber wir sprechen hier über die Grundidee).
Der Adressbus und der Datenbus sind getrennt, sodass sie unterschiedliche Größen haben können. Für bestimmte Adressbusgrößen gibt es viele Techniken, um mehr Speicher als die Registerbitbreite zu adressieren
Der häufigste Weg ist , die Adressbusbreite irgendwie zu erhöhen
Verwenden mehrerer Register für die Adresse
X
, Y
und die Z
Datenregister - Adressierung maximal 64 KB RAM zu ermöglichen. Diese wiederum können mit RAMPX
, gepaart werden RAMPY
, RAMPZ
um in noch größeren Versionen auf höhere RAM-Adressen zuzugreifen. Dies gilt auch SPH
für die High-Bytes des Stack-Pointers zusätzlich zu den SPL
Varianten mit mehr als 256 Bytes RAM 1H
& L
, B
& C
, D
& E
, die zusammen als 16-Bit-Adressregister verwendet werden könnenVerwenden eines einzigen großen Sonderregisters, das größer als die natürliche Größe für die Adressierung ist
Verwenden eines speziellen Registers für den oberen Teil der Adresse . Beim Adressieren eines Speichers werden standardmäßig die 8 niedrigen Bits der Adresse aus dem 8-Bit-Direkt- oder 8-Bit-Register eines 8-Bit-Mikrocontrollers entnommen, während die hohen Bits durch den Wert des anderen Adressregisters ersetzt werden.
call
oder goto
Befehl werden 8 oder 9 niedrige Bits der Adresse durch das Unmittelbare angezeigt und der Rest wird vom aktuellen Programmzähler entnommen. Wenn Sie also auf etwas zugreifen, das nicht weit vom aktuellen Segment entfernt ist, wird nur 1 Befehl benötigt, während für weitere Adressen 2 Befehle erforderlich sind (um die hohen Bits zu setzen).PC
während bedingungslos gesprungen wird.Ein weiterer Weg, dies zu erreichen, ist das Memory Banking . Dies ist eine nützliche Methode, die heutzutage in einigen Architekturen noch verwendet wird. In diesem Modell ist der Speicher in mehrere unterteilt Bänke unterteilt . Jedes Mal können Sie nur eine bestimmte Bank ansprechen. Oft gibt es eine globale Bank oder einen Adressbereich, die jederzeit sichtbar sind, aber für andere Teile müssen Sie die Bank bei Bedarf wechseln.
Es gibt auch eine nicht ganz übliche Technik, die aber im Intel 8051 zu finden ist . Als Mikrocontroller mit 8-Bit-Datenadresse kann er maximal 256 Adressen haben. Die Hälfte des Speicherplatzes (der obere Teil) wird für Sonderfunktionsregister ( SFR ) verwendet, wodurch der reale RAM-Speicher auf nur 128 Byte begrenzt wird. Die Hersteller der modernen 8051-Serie haben jedoch eine clevere Möglichkeit gefunden, dies durch getrennten Speicherzugriff zu überwinden . Die direkte Adressierung greift auf den SFR zu, während die indirekte Adressierung auf den oberen Teil des RAMs zugreift. Dies bedeutet, dass Sie jetzt 256 + 128 = 384 adressierbare Bytes haben.
1 https://en.wikipedia.org/wiki/Atmel_AVR_instruction_set#Memory_addressing_instructions
Die kleinsten Kerne haben ≤256 Byte Datenadressraum (dh ≤128 Byte RAM, nachdem E / A-Ports und andere reservierte Adressen entfernt wurden) und ≤8192 Byte (8 KB) Programm-ROM. Diese haben nur einen 8-Bit-Stapelzeiger (in SPL) und unterstützen nur die relativen 12-Bit-Sprung- / Aufrufanweisungen RJMP / RCALL. (Da der AVR-Programmzähler 16-Bit-Wörter und keine Bytes zählt, reicht ein 12-Bit-Versatz aus, um 213 Bytes ROM zu adressieren.)
Je nach Bedarf stehen zusätzliche Speicheradressierungsfunktionen für den Zugriff auf verfügbare Ressourcen zur Verfügung:
- Modelle mit> 256 Bytes Datenadressraum (≥256 Bytes RAM) haben einen 16-Bit-Stapelzeiger, wobei sich die obere Hälfte im SPH-Register befindet.
- Modelle mit mehr als 8 KB ROM fügen die 2-Wort- (22-Bit-) JUMP- und CALL-Anweisungen hinzu. (Einige frühe Modelle erleiden ein Durcheinander, wenn auf eine Sprunganweisung eine 2-Wort-Anweisung folgt.)
- Modelle mit> 64 KB ROM fügen den ELPM-Befehl und das entsprechende RAMPZ-Register hinzu. LPM-Anweisungen erweitern die ROM-Adresse in Z auf Null; ELPM-Befehle stellen dem RAMPZ-Register High-Bits voran. Dies ist nicht dasselbe wie der allgemeinere LPM-Befehl. Es gibt "klassische" Modelle mit nur der Nulloperandenform von ELPM (ATmega103 und at43usb320). Wenn die automatische Inkrementierung verfügbar ist (die meisten Modelle), wird die gesamte 24-Bit-Adresse einschließlich RAMPZ aktualisiert.
- (Seltene) Modelle mit> 128 KiB ROM verfügen über einen 3-Byte-Programmzähler. Unterprogrammaufrufe und -rückgaben verwenden ein zusätzliches Byte Stapelspeicherplatz, es gibt ein neues EIND-Register, um zusätzliche hohe Bits für indirekte Sprünge und Aufrufe bereitzustellen, und es gibt neue erweiterte Befehle EIJMP und EICALL, die EIND: Z als Zieladresse verwenden. (Die vorherigen IJMP- und ICALL-Anweisungen verwenden null-erweitertes Z.)
- (Seltene) Modelle mit> 64 KB RAM-Adressraum erweitern die 16-Bit-RAM-Adressierungsgrenzen mit RAMPX-, RAMPY-, RAMPZ- und RAMPD-Registern. Diese stellen zusätzliche hohe Bits für Adressierungsmodi bereit, die die X-, Y- oder Z-Registerpaare oder die Direktadressierungsanweisungen LDS / STS verwenden. Anders als beim ROM-Zugriff gibt es keine eindeutigen "erweiterten" Anweisungen. stattdessen werden die RAMP-Register bedingungslos verwendet.
Fast alle 8-Bit-Prozessoren können eine 16-Bit-Adresse aus einem Teil niedriger und einem Teil hoher Ordnung bilden. Bei einigen Prozessoren, einschließlich des ursprünglichen 8080, gibt es Register, die dazu bestimmt sind, den oberen und unteren Teil einer Adresse zu halten (obwohl es vom Standpunkt eines Programmierers einige Register wie den Stapelzeiger des 8080 geben kann, die keine Anweisungen bieten, um sie getrennt zu adressieren). In einigen anderen Prozessoren gibt es keine Register für die obere oder untere Hälfte einer Adresse, sondern Adressen werden "on the fly" zusammengestellt. Beispielsweise lädt der Befehl "LDA $ 1234, X" auf dem 6502 den Akkumulator mit der Adresse, die durch Addieren von $ 1234 zum 8-Bit-X-Register gebildet wurde [angenommen, er enthält $ F0]. Die Ausführung dieser Anweisung würde in 4 oder 5 Schritten erfolgen:
Die Übertragung des gelesenen Bytes zum Akkumulator überlappt das Abrufen des nächsten Befehls. Wenn Schritt 3 für viele Operationen keinen Übertrag erzeugt hätte, hätte Schritt 4 die richtige Adresse gelesen, und die Ausführung könnte direkt von Schritt 4 zum nächsten Befehl springen und Schritt 5 umgehen.
Wenn man die Abfolge der Operationen untersucht, wird man feststellen, dass eine Little-Endian-Architektur in den meisten Fällen (wenn auch nicht in der gezeigten) einen deutlichen Vorteil gegenüber einer Big-Endian-Architektur hat, obwohl die ALU einen Durchführungszyklus benötigt Außerdem ist es möglich, ein Byte von der berechneten Adresse zu lesen, ohne auf das ALU-Ergebnis zu warten, da normalerweise das abgerufene High-Byte das High-Byte des Zieloperanden ist. Auf einem Big-Endian-Computer mit einer 8-Bit-ALU würde ein indizierter Ladevorgang mindestens 5 Zyklen dauern (da die untere Hälfte der Adresse erst in Schritt 3 gelesen und somit in Schritt 4 berechnet würde).
Datenbusleitungen (Pins) und Adressleitungen (Pins) sind vollständig getrennt. Einfach ausgedrückt, bestimmen Datenbusleitungen die maximale Anzahl von Bits, die einzeln übertragen (und im Speicher gespeichert) werden können, wohingegen Adressleitungen die maximale Anzahl von Speicher- "Zellen" bestimmen, die ausgewählt werden können.
Es war hauptsächlich eine Marketing-Sache, dass 32-Bit-x86-CPUs nicht mehr als 4 GB RAM adressieren konnten. Ich erinnere mich, dass es irgendwo A33-34-Pins auf Pentium 4-CPUs gab.
Es ist oft wahr, dass es eine Beziehung zwischen der Größe des adressierbaren Speichers und der Größe des internen Registers gibt, obwohl die Beziehung aus verschiedenen Gründen variiert. 256 Byte Adressraum galten schon in den Anfängen der Mikroprozessoren als zu klein, sodass die meisten 8-Bit-Prozessoren 16-Bit-Adressen (2 Byte) erzeugten, die 64 Kilobyte adressierten. Mit dem Bank-Switching (im Wesentlichen unter Verwendung bestimmter E / A-Leitungen, um noch mehr Adressleitungen zu erzeugen) war es jedoch möglich, viel mehr zu haben.
In den ersten 16- und 32-Bit-Prozessoren waren nicht immer genügend Pins auf dem Gerät vorhanden, um den gesamten Speicherplatz zu erreichen, den ihre internen Adressregister adressieren konnten. Beispielsweise gab es beim Motorola 68000 nur genügend Adresspins (24), um 16 MB RAM zu adressieren, obwohl die internen Adressregister 32 Bit breit waren.
Ich werde diese Frage speziell für die von Ihnen erwähnten AVR-Controller beantworten. Das Grundprinzip gilt auch für viele andere 8-Bit-Architekturen.
AVRs sind 8-Bit-Kerne. Dies bedeutet, dass sie 8-Bit-Register haben. 8 Bit reichen jedoch nicht aus, um auf eine nutzbare Speichermenge zuzugreifen. Daher kann der AVR-Kern einen bestimmten Satz von Registern verwenden, die als 16-Bit-Zeigerregister kombiniert sind. Ein Beispiel hierfür sind die Register r30 und r31 (auch als ZL und ZH bezeichnet). Zusammen bilden sie den Z-Zeiger.
In der Assembly würde das Lesen eines Bytes an der Adresse 0x1234 so aussehen:
ldi ZL, 0x34 ; Load r30 (ZL) with low byte of address
ldi ZH, 0x12 ; Load r31 (ZH) with high byte of address
ld r16, Z ; Load byte to r16
Die AVR-Familie verfügt über 3 Registerpaare, die hierfür verwendet werden können. Sie wurden speziell für Hardware entwickelt, um solche Vorgänge zu ermöglichen.
Wenn Sie in einer höheren Programmiersprache wie C programmieren, übernimmt der Compiler diese Aufgabe.
Hinweis: Einige AVRs unterstützen sogar größere Speichergrößen als 64 KB. Diese Steuerungen verfügen über ein spezielles Funktionsregister, in das vor dem Zugriff zusätzliche Bits der Adresse geschrieben werden. Die Adresse besteht daher aus folgenden Bits (MSB bis LSB):
Sonderfunktionsregister (in der Regel 1 Byte), ZH (8 Bit), ZL (8 Bit).
Die 8-Bit-AVRs von Atmel verwenden tatsächlich eine 16-Bit-Datenadresse. Sie haben zahlreiche andere 16-Bit-Register und sogar einige 16-Bit-Timer. Da es sich nur um einen 8-Bit-Prozessor handelt, werden normalerweise zwei Taktzyklen zum Laden eines 16-Bit-Registers verwendet.
Wikipedia erklärt es ziemlich gut:
Acht-Bit-CPUs verwenden einen 8-Bit-Datenbus und können daher in einem einzigen Maschinenbefehl auf 8 Datenbits zugreifen. Der Adressbus ist aus praktischen und wirtschaftlichen Gründen in der Regel doppelt so breit wie ein Oktett (dh 16 Bit). Dies impliziert auf den meisten 8-Bit-Prozessoren einen direkten Adressraum von nur 64 KB.
Die Vorstellung, dass die "Bitbreite" eines Prozessors die maximale Menge an RAM festlegt, die der Prozessor ansprechen kann, ist einer der am weitesten verbreiteten Mythen beim Rechnen. Tatsächlich ist die Industriegeschichte nur mit CPUs übersät, für die diese Beziehung nicht bestand.
HP 21MX, HP 1000: 16-Bit-CPU, Arbeitsspeicher auf 16 MB
PDP-11: 16-Bit-CPU, Speicher auf 4 MB
VAX-11/780: 32-Bit-CPU, Arbeitsspeicher auf 512 MB
usw. usw.