Mein Professor für eingebettete Systeme bezeichnet die Speicherorte von Registern immer wieder als ihre jeweiligen "Adressen". Das verwirrt mich; Ich hatte immer den Eindruck, dass die CPU-Register in jedem Mikroprozessor keine Adressen haben, da sie sich nicht im Hauptspeicher befinden (sie befinden sich im Mikroprozessor selbst). Ich bin auch verwirrt darüber, worauf wir uns beziehen, wenn wir den "Speicherort des Registers" sagen - auch hier befindet es sich nicht im Hauptspeicher.
Warum beziehen wir uns vor diesem Hintergrund mit "Adressen" auf die Speicherorte der CPU-Register? Haben alle/einige Register Adressen?
Ich habe darüber nachgedacht und festgestellt, dass sie möglicherweise mit bestimmten Hauptspeicherorten "verbunden" sind und den Zugriff auf die in den Registern gespeicherten Werte ermöglichen. Um diesen Gedanken zu erweitern, ist das Memory Mapping?
Ich sollte auch hinzufügen, dass wir speziell mit dem LPC1768-Mikrocontroller von NXP arbeiten, der den ARM Cortex-M3-Mikroprozessor verwendet.
Es hängt vom jeweiligen Prozessor ab, ob "Register" im selben Adressraum wie reguläre Datenspeicher oder getrennt sind. In beiden Fällen, wenn es mehrere davon gibt, braucht jeder noch eine Adresse.
Nehmen wir an, der Prozessor hat 16 Register, die eng mit der CPU gekoppelt und getrennt vom Datenspeicher implementiert sind. Diese Register müssen noch irgendwie identifiziert werden. In diesem Fall wäre eine 4-Bit-Adresse erforderlich, um einzelne Register zu unterscheiden. In einer RISC-Architektur würde die 4-Bit-Adresse eines oder mehrerer Register, an denen ein Befehl arbeitet, in den Befehlscode aufgenommen. Beispielsweise könnte der ADD-Befehl den Wert eines Quellregisters in ein Zielregister addieren. Dieser Befehl würde 4 Bits zum Identifizieren des Quellregisters und weitere 4 Bits zum Identifizieren des Zielregisters enthalten. Die Dokumentation kann sich auf diese Register mit "Nummer" 0 bis 15 beziehen, aber das ist wirklich die Adresse, an der sich die Register in einem speziellen kleinen Speicher der CPU befinden.
Zusätzlich zu dem oben Gesagten könnten diese Register, selbst wenn ein Prozessor über spezielle dedizierte Register verfügt, in den Allzweck-Datenadressraum abgebildet werden. Verweise auf diese Adressen werden abgefangen und auf die internen Register verwiesen.
Es gibt viele Schemata da draußen, aber wenn Sie mehr als ein Register haben, müssen diese Register irgendwie voneinander unterschieden werden, und innerhalb der Hardware, die mit einer "Adresse" versehen sein wird, ob es in der Dokumentation so heißt oder nicht.
Die Quelle der Verwirrung ist, dass es (im Allgemeinen) zwei Arten von Dingen gibt, die als "Register" bezeichnet werden können.
Das erste ist wahrscheinlich das, womit Sie vertraut sind: In ARM ist es registers R0, R1, R2, ... R12, SP, LR, PC
und in x86 ist es eax, ebx, ecx, edx, ebp
und so weiter. Diese können auch als „ Kernregister “ oder „ Prozessorregister “ bezeichnet werden. Sie haben keine Adressen im Systemspeicherbereich und können nur durch spezielle Befehle aufgerufen werden.
Das andere sind die Register, die verschiedene Hardwareblöcke (Peripheriegeräte) in der CPU selbst oder außerhalb davon steuern können. Auf LPC1768 und vielen anderen eingebetteten Prozessoren sind sie normalerweise speicherabgebildet und haben deshalb Adressen. Beispielsweise befindet sich der UART0-Block an der Adresse 0x4000C000, und dort müssen Sie lesen oder schreiben, um mit ihm zu kommunizieren. Zur Unterscheidung von den Kernregistern können sie „ Peripherieregister “ oder „ Hardwareregister “ genannt werden.
Auf einigen Low-End-8-Bit-Mikrocontrollern wie 8051 oder PIC gibt es möglicherweise überhaupt keine Kernregister außer vielleicht einem Akkumulator, und alle anderen Register werden in verschiedene Speicherbereiche wie "internes RAM" (für vorübergehende Speicherung / Berechnung) oder "Special Function Registers" (SFR) Speicher für die Steuer- und Peripherieregister. Darin haben "Register" fast immer eine Adresse.
Größere ARMs haben auch Coprozessorregister , die verwendet werden können, um verschiedene Kernfunktionen (z. B. MMU oder Cache) mit Anweisungen wie MRC
oder zu steuern MCR
. Diese Register ähneln den Kernregistern darin, dass sie keine Speicheradresse, sondern nur eine Nummer haben.
Außerdem können Sie auf x86 E/A - Ports haben , auf die über Anweisungen in
und zugegriffen werden out
kann, die zur Steuerung einiger Hardwareblöcke verwendet werden können. Diese ähneln in ihrer Funktion den peripheren Registern, werden aber normalerweise nicht als solche bezeichnet.
register field
Opcode (dem Maschinencode-Befehlswort) verwendet und kann nicht mit Speicheradressen verwechselt werden (ihre Positionen im Opcode-Format sind unterschiedlich , und die Felder sind unterschiedlich groß).Sie haben Recht, dass sich einige Register nicht im Hauptspeicher befinden, sondern im Mikroprozessor selbst, und dass diese Register an bestimmten Stellen im Speicher abgebildet sind.
Der LPC1768-Mikrocontroller hat nur 64 KB RAM (was Sie meiner Meinung nach mit Hauptspeicher meinen), jedoch einen 32-Bit-Adressbus und 4 GB Gesamtadressraum. Der Rest dieses Adressraums enthält den Flash-Speicher, in dem Ihr Programm gespeichert ist, und die Register für alle Peripheriegeräte (z. B. die Zustände der Ausgangspins oder den ADC).
Wenn Sie versuchen, auf einen speicherabgebildeten Ort zuzugreifen, erkennt die Logik im Mikrocontroller normalerweise, wo sich die Speicheradresse physisch befindet, und steuert Steuerleitungen, damit die Daten dorthin gelangen, wo sie beabsichtigt waren, unabhängig davon, ob sie sich im RAM befinden, a GPIO-Port oder ein peripheres Steuerregister.
Dies vereinfacht das Schreiben von Software, da Sie sich nicht allzu viele Gedanken darüber machen müssen, wo sich die Register physisch befinden, und macht das Kompilieren höherer Sprachen (wie C) viel einfacher.
Im speziellen Fall des LPC1768 sehen wir im Datenblatt ( http://www.nxp.com/documents/data_sheet/LPC1769_68_67_66_65_64_63.pdf ) die Adresskarte auf Seite 20 (Abbildung 4), die zeigt, wo sich alle befinden Peripheriegeräte werden im Speicher abgebildet.
Natürlich enthält der Prozessor auch eine Handvoll interner Register, die nicht speicherzugeordnet sind. Auf diese kann viel schneller zugegriffen werden als auf alles im Adressraum, da die Speicherverwaltungslogik im Vergleich zum Kern langsam ist und als temporärer Speicher verwendet wird während Operationen. Ein Teil der Aufgabe eines Compilers besteht darin, Daten in Registern zu speichern und sie für Sie aus dem/in den Speicher zu verschieben.
Wie andere gesagt haben, hängt es von der Mikrocontroller-Familie ab. Und es hängt davon ab, was Sie mit registrieren meinen.
Der msp430 zum Beispiel hat zwei Sätze von "Registern". Die erste ist die RISC-Registerdatei mit 16 16-Bit-Registern. Dazu gehören die Register Programmzähler, Stapelzeiger, Status und Konstantengenerator sowie 12 allgemeine Register. Dies sind Register im traditionellen Architekturgebrauch des Wortes.
Der zweite Registersatz ist alles andere. Ports, Peripheriegeräte, Interrupts usw. Diese sind Teil der einzelnen Speicherdatei und teilen sich den Speicherplatz mit dem allgemein verwendeten RAM und Flash (Code Space).
Beispielsweise hat der msp430g2231 ein Ausgangsregister für Port 1 an der Speicheradresse 0x21.
Sie können auf das Register mit dem Registernamen p1out zugreifen, aber das ist nur ein Zeiger auf die 8-Bit-Speicheradresse 0x21. Am wichtigsten ist, dass der Compiler es so sieht. Die Header-Datei, in diesem Fall msp430g2231.h, definiert „p1out“ als 0x0021. Abgesehen von der RISC-Registerdatei bedeutet die übliche Verwendung von Register nur eine Speicheradresse für eine x-spezifische Option. Was Sie als Register p1out sehen, ist genau so, wie eine höhere Sprache Ihnen das Programmieren erleichtert, anstatt sich Speicherkarten zu merken.
Wenn Sie einen Zeiger auf die Speicheradresse 0x27f verwenden, würden Sie stattdessen aus dem RAM lesen. Zeiger auf Speicheradresse 0xffdf, und Sie würden stattdessen Ihren kompilierten Code lesen. Alles, was ein Register ist, ist eine Speicheradresse für eine spezielle Funktion.
Als Oberbegriff bedeutet „Register“ nur einen Ort, an dem Sie Informationen speichern („registrieren“) können, nicht mehr.
Die meisten Architekturen reservieren den Begriff Register für Orte innerhalb der CPU, die durch Bits in einem Befehl identifiziert werden und auf die oft viel schneller zugegriffen werden kann als auf allgemeinen Massenspeicher ("RAM"). (Und oft kann in einem Ausführungszyklus auf 2 oder 3 Register parallel zugegriffen werden.)
Die PIC-Dokumentation von Microchip bezieht sich jedoch beispielsweise auf alle adressierbaren Stellen als Register, sogar einschließlich RAM. Wenn Ihr Professor diese Verwendung des Begriffs kopiert, sollte er Sie meiner Meinung nach darüber informieren, dass dies nicht die Art und Weise ist, wie der Begriff "Registrieren" heutzutage üblicherweise verwendet wird. (Wie ich es hoffentlich in meinen PIC-Assembler-Kursen getan habe.)
Register haben Adressen, obwohl sie sich im Allgemeinen nicht im Speicher befinden.
Denken Sie eine Minute darüber nach: Eine Adresse bezeichnet einen Ort in einem Raum, wo der Speicher nur eine Instanz eines Raums ist. E/A hat oft einen eigenen Adressraum; In einigen Mikrocontroller-Architekturen sind Codespeicher und Datenspeicher getrennte Räume.
Und so können Register auch ihren eigenen Platz haben: Manchmal haben FP- und Integer-Register (und auf dem 68000, glaube ich, Adressregister) jeweils ihren eigenen separaten Platz.
Eine Frage ist: Wie können wir feststellen, ob sich Adresse 1 auf Byte 1 im Speicher, I/O-Port 1 oder Register 1 bezieht? Normalerweise aus dem Kontext: in einer IN- oder OUT-Anweisung offensichtlich ein Port. Bei einem Register-zu-Register-Befehl handelt es sich um eine Registeradresse. In einem Ladebefehl gibt es eine (große) Speicheradresse und eine (kleine) Registeradresse und so weiter.
In einem ARM-Kern ist eine Speicheradresse normalerweise eine 32-Bit-Zahl; eine Registeradresse ist eine 5-Bit-Zahl.
Wenn man eine Adresse als eine Menge von k
Bits definiert, die verwendet werden können, um ein Element aus einer Menge von bis zu 2^k
Elementen auszuwählen, dann ist es üblich, dass viele Register in vielen Prozessoren und Controllern Adressen haben, aber auch Controller einige haben Register, die von Schaltkreisen abgetastet werden, die bestimmte Bedingungen erkennen, und die nicht über irgendeine Art von Adresse identifizierbar sind. Es ist jedoch wichtig zu beachten, dass in vielen Fällen die Adressleitungen, die CPU-Register steuern, keine Beziehung zu den Adressleitungen haben, die mit größeren Speichersystemen verbunden sind. Als solche existieren Register-"Adressen" oft in einem völlig getrennten "Universum" von Speicheradressen.
Bei den meisten Prozessoren werden Register-"Adressen" immer entweder intern von der Prozessorlogik außerhalb der Kontrolle des Programmierers generiert oder von bestimmten Bits in jedem Befehl abgerufen. Der einzige Weg, wie ein Änderungscode per Software beeinflussen könnte, welches Register von einem bestimmten Befehl abgerufen werden sollte, wäre, die entsprechenden Bits innerhalb dieses Befehls zu patchen. Auf dem PIC von General Instruments, dessen Design in Form des Microchip PIC weiterlebt, würde Hardware den Inhalt eines anderen Registers an Adresse 3 ersetzen, wenn ein Opcode nur Nullen für eine Adresse spezifiziert. Dies ermöglicht dem Code, Berechnungen zur Auswahl zu verwenden eine Adresse.
Das vielleicht Wichtigste, was man über Adressen wissen muss, ist, dass es möglich ist, dass ein System unterschiedliche Adressräume hat, die tatsächlich in verschiedenen Universen existieren. Beim 8051 zum Beispiel gibt es, je nach Zählweise, mindestens vier verschiedene Adressräume, möglicherweise sogar sechs; vier von ihnen sind völlig unabhängig (die Anweisungen:
mov a,80h ; Direct address space
mov a,@r0 ; Assume R0 = 80h
movc a,@a+dptr ; Assume A = 0 and DPTR = 80h
movx a,@dptr ; Assume DPTR = 80h
Alle rufen Daten von "Adresse 80h" ab, aber sie lesen vier unabhängige Dinge: eine Adresse im E / A-Bereich (das Datenregister von Port 0, glaube ich), das interne Datenregister 80h, den Codespeicher bei Adresse 0x0080 und den externen Datenspeicher bei Adresse 0x0080 . In vielen Systemen hätten diese Dinge tatsächlich keinerlei Beziehung zueinander. Die Tatsache, dass ein Register auf eine bestimmte Adresse in einem Universum reagiert, sagt wenig oder gar nichts darüber aus, ob es auf diese oder irgendeine andere Adresse in einem anderen Universum reagiert.
RISC bedeutet "Computer mit reduziertem Befehlssatz". Sie reduzieren die Größe des Befehlssatzes teilweise, indem Sie nur eine Art von Datenspeicherort haben, der Register, RAM oder I/O umfasst.
Damals, als die Leute diese Ideen ernst nahmen, waren die beiden erwarteten Vorteile von RISC-Designs, dass Sie den Prozessor viel schneller machen könnten, wenn Sie es viel einfacher machten, und dass Sie Ihren Programmcode optimieren könnten, wenn Sie jede Speicheradresse für alles verwenden könnten. Anstatt alles zum Laden und Entladen zu zwingen, gehen Sie durch das ALU-Register für Arithmetik, das Speicheradressenregister für die Speicheradressierung usw.
Zwei Überbleibsel dieser Denkweise sind: (1) Wir haben Prozessoren, die so tun, als seien alle Register gleich, indem sie Register in den Speicherraum abbilden, und (2) wir haben Professoren, die so tun, als seien alle Register gleich, indem sie Speicherorte der Register aufrufen.
Sei tolerant. Es war ein wichtiges Forschungsgebiet für Doktoranden, das einen signifikanten und nachhaltigen Einfluss auf die Art und Weise hatte, wie einige Prozessoren entworfen wurden.
Wenn ich mich recht erinnere, könnte der 8051 über Speicheradressen auf die Register zugreifen, aber dies ist nicht der allgemeine Fall für alle Prozessoren. Die ARM-Prozessoren haben dazu keine Möglichkeit, auf die Mehrzweckregister r0-r15 kann auf dem Speicherbus nicht zugegriffen werden.
Cheveston
Cheveston
Olin Lathrop