Grundlegendes zum „Modell mit flachem Speicher“ und zum „Modell mit segmentiertem Speicher“


7

Ich versuche, Flat-Memory-Modell und Segmented-Memory-Modell zu verstehen.

Werden das flache Speichermodell und das segmentierte Speichermodell durch die CPU-Architektur oder das Betriebssystem oder beides bestimmt?

Oder werden sie nicht durch die CPU-Architektur oder das Betriebssystem bestimmt, sondern sind stattdessen für Programmierer auf jedem Computer mit einer CPU-Architektur und einem installierten Betriebssystem verfügbar?

Wenn dies das letztere ist, welche Arten der Programmierung müssen das flache Speichermodell und das segmentierte Speichermodell berücksichtigen? Assembler, C und / oder andere Programmiersprachen?

Hier sind einige Zitate aus Wikipeda, die mich verwirren.

Aus http://en.wikipedia.org/wiki/Address_space#Memory_models :

Frühe x86-Computer verwendeten die Adressen des segmentierten Speichermodells basierend auf einer Kombination von zwei Zahlen: einem Speichersegment und einem Offset innerhalb dieses Segments. Einige Segmente wurden implizit als Codesegmente behandelt, die für Anweisungen, Stapelsegmente oder normale Datensegmente vorgesehen waren. Obwohl die Verwendungen unterschiedlich waren, wiesen die Segmente keinen unterschiedlichen Speicherschutz auf, der dies widerspiegelte.

Heutzutage bevorzugen viele Programmierer ein flaches Speichermodell, bei dem alle Segmente (Segmentregister) im Allgemeinen auf Null gesetzt sind und nur Offsets variabel sind.

Aus http://en.wikipedia.org/wiki/Flat_memory_model#Comparison :

Flat-Memory-Modell

  • Nicht geeignet für allgemeine Computer- oder Multitasking-Betriebssysteme, sofern nicht durch zusätzliche Speicherverwaltungshardware / -software erweitert; Dies ist jedoch fast immer bei modernen CISC-Prozessoren der Fall, die eine erweiterte Speicherverwaltungs- und Schutztechnologie über ein flaches Speichermodell implementieren. Linux verwendet zB ein flaches Speichermodell, vergleiche X86_memory_segmentation # Practices.

Segmentiertes Speichermodell

  • Implementiert in den Originalen Intel 8086, 8088, 80186, 80286 und unterstützt von 80386 und allen nachfolgenden x86-Maschinen bis hin zu heutigen Pentium- und Core 2-Prozessoren. Dieses Speichermodell ist seitdem in den x86-Maschinen erhalten geblieben, die nun einen Multimodus-Betrieb ermöglichen und ohnehin selten im kompatiblen segmentierten Modus arbeiten.

Antworten:


7

Das verwendete Speichermodell wird durch zwei Dinge bestimmt:

  1. Die verwendete CPU und die unterstützten Modi
  2. Das Betriebssystem und was es verwendet

Aus Sicht eines Programmierers erhalten Sie, sofern Sie nicht an Kernel-Code arbeiten, das, was das Betriebssystem Ihnen bietet. Was in den meisten modernen Betriebssystemen ein ausgelagertes Speichermodell ist.

Für Code, der auf einem modernen Betriebssystem im Userspace ausgeführt wird, ist das Speichermodell in Bezug auf den Prozess flach. Dies liegt daran, dass das Betriebssystem dem Prozess einen virtuellen Speicherplatz zur Verfügung stellt, in dem alle Paging-, Auslagerungs- und sonstigen Probleme, die mit dem Speicher auftreten können, ausgeblendet werden. Diese Abstraktionsebene ist sehr, sehr nützlich, da sie Programmierer nicht zwingt, zum Wohle des gesamten Systems gut mit dem Speicher umzugehen.

In der Vergangenheit war dies nicht immer der Fall.

In Windows 3.1x, MacOS bis Version 9 und Novell NetWare fehlten einige der Speicherschutzfunktionen, die unter Linux / Windows / OSX für selbstverständlich gehalten werden. Insbesondere NetWare verfügte über einen großen Speicherplatz, der dem gesamten laufenden Code zur Verfügung gestellt wurde, sodass ein Fehler, der versuchte, auf den nicht zugewiesenen Speicher zuzugreifen, diesen Speicher tatsächlich abrufen und häufig das gesamte System zum Absturz bringen konnte. Programmierer, die für NetWare programmieren, mussten aus diesem Grund sehr vorsichtig mit der Speicherverwaltung umgehen, und dies in einem Ausmaß, mit dem sich Linux- / Windows- / OSX-Programmierer nicht befassen müssen.

Und doch verwendete NetWare ein ausgelagertes Speichermodell. Es stellte nicht jedem Prozess einen virtuellen Speicherplatz zur Verfügung, sondern gab ihm den tatsächlichen Speicherplatz.

Das verwendete Speichermodell ist nicht für alle Programmierungen flexibel, sondern der Hardware am nächsten. Kernel-Programmierung und Embedded Device-Programmierung sind die Bereiche, in denen solche Dinge sehr wichtig sind.


Vielen Dank! Wenn das segmentierte Speichermodell nicht mit den verschiedenen Segmenten (BSS-Segment (Block Started by Symbol), Textsegment und Datensegment) in einer Objektdatei verknüpft ist? Ich habe diese Segmente in Objektdateien ziemlich oft gehört ( en.wikipedia.org/wiki/Object_file#Object_file_formats ), daher kann es sein, dass sie nicht mit den Segmenten im segmentierten Speichermodell zusammenhängen, obwohl sie alle als "Segmente" bezeichnet werden.
Tim

5

"Speichermodell" ist sowohl ein Konzept auf niedriger als auch (relativ) hoher Ebene.

Früher herrschte ein gewisser "Krieg" zwischen Prozessoren mit einem segmentierten Speichermodell und solchen mit einem "ausgelagerten" oder "abgebildeten" Speichermodell. Die Maschinen der Burroughs B5000-Serie und die Plessey 250 verwendeten ein segmentiertes Speichermodell mit "Fähigkeiten" (oder "Deskriptoren"). Das heißt, der physische Speicher wurde nicht als konzeptionelle Seiten mit fester Größe verwaltet, sondern als Segmente mit variabler Länge, wobei jedes Segment einer logischen Entität (z. B. einer Prozedur oder einem Objekt) entspricht. Zur Adressierung zwischen Segmenten wurden "Fähigkeitsregister" verwendet, die nur geschützt geladen werden konnten und die die physikalische Adresse eines Segments, die Länge des Segments und die Berechtigungen (z. B. Lesen / Schreiben / Ausführen) enthielten, die ausgeführt wurden Programm wurde gegeben, um das Segment zu verweisen.

Diese Systeme liefen zufrieden, als "ausgelagerte" Systeme immer noch Probleme hatten, den Boden zu erreichen.

Der ursprüngliche PC basierte auf dem 8086-Prozessor, der die segmentierte Architektur eines armen Mannes unterstützen sollte. Es gab IIRC, vier Segmentregister, die ausgewählt werden konnten, um zu einem allgemeinen 16-Bit-Registerwert hinzugefügt zu werden, um eine 20-Bit-Adresse zu erzeugen. Die Theorie war, dass diese Register in einer Software verwaltet werden, die der Verwaltung der Burroughs- und Plessey-Systeme mit etwas mehr Hardwareunterstützung ähnelt. Bevor jedoch eine gute Software zur Nutzung dieser Funktion erstellt werden konnte, wurde DOS auf den 8086 gekludert, so dass die Funktion nie wirklich effektiv genutzt wurde.

Was nun besser ist, spielt keine Rolle mehr, da das segmentierte Modell in keiner "realen" (nicht experimentellen) Umgebung existiert. Aber damals schnitt das segmentierte Modell im Allgemeinen besser ab und ermöglichte es dem Betriebssystem, robuster zu sein. Der größte negative Faktor war, dass es den Compilern und in gewissem Umfang den Programmierern Beschränkungen auferlegte, die den Einstellungen vieler Programmierer im "Wilden Westen" damals und heute nicht entsprachen.

Das "ausgelagerte" Modell

Bei einem "ausgelagerten" Modell wird davon ausgegangen, dass der Adressraum in "Seiten" einer bestimmten Größe unterteilt ist (obwohl in einigen Fällen mehrere verschiedene Seitengrößen unterstützt werden). Im Allgemeinen liegt die Seitengröße irgendwo zwischen 256 Byte und 64 KB (immer eine Potenz von 2). Es wird auch angenommen, dass die Hardware irgendeine Art von Unterstützung für die Adressumsetzung enthält, so dass "logische" Adressen (Adressen im "Adressraum" des Programms) "physikalischen" Adressen (Adressen im RAM) zugeordnet werden können.

Ein ausgelagertes Modell kann aus zwei Hauptgründen implementiert werden:

  1. Mehrere unterschiedliche Threads / Prozesse können unterschiedliche Adressräume haben, wobei jeder mit "Null" (oder einer anderen Standardadresse) beginnt, ohne dass das Betriebssystem den gesamten möglichen Adressraum für einen Thread / Prozess als einen zusammenhängenden Block vorbelegen muss .
  2. Aktivierung des "virtuellen Speichers", indem einzelne Seiten im logischen Adressraum auf die Festplatte "ausgelagert" werden und später neu geladen werden, wenn das Programm versucht, auf sie zu verweisen.

Es gibt auch kleinere Funktionen der Hardware für die Seitenübersetzung, die verwendet werden können, z. B. das Festlegen von Lese- / Schreib- / Ausführungsberechtigungen, damit einige Seiten von Prozessen / Threads usw. "gemeinsam genutzt" werden können.

Das "flache" Modell

Ohne das Harvard-Modell zu berücksichtigen, das wohl das allererste Computerspeichermodell war, war das flache von Neumann-Speichermodell das erste Modell, das allgemeine Verwendung fand. Dies ist im Grunde genommen das - ein "flacher" Adressraum von nicht unterscheidbaren Wörtern (erst sehr spät im Spiel bytes), der an der Adresse Null begann und sich nach oben bis zur "Spitze" des verfügbaren Speichers fortsetzte. Ein Teil des Speichers am "unteren" oder "oberen" Ende des Speichers wäre für eine Art "Lader" reserviert, der Rest steht dem einzelnen ausführenden Programm zur Verfügung. Es wurde jeweils ein Programm ausgeführt, wobei das Programm alle bis auf diesen kleinen reservierten RAM-Bereich verwenden konnte.

Langsam änderten sich die Dinge, und der kleine reservierte Bereich wurde größer und enthielt eine Art Betriebssystem, aber immer nur ein Programm gleichzeitig. Im weiteren Verlauf der Zeit wurden verschiedene Tricks erfunden, die es beispielsweise bestimmten Spezialprogrammen ermöglichen, in einer "Ecke" des Speichers ausgeführt zu werden, Spool-Programme usw. mit den Programmen des Benutzers zu koexistieren.

Aber der Drang nach "Multiprogramming" übte Druck aus. Einige Systeme fügten grobe Adresszuordnungshardware hinzu, um zu ermöglichen, dass mehrere Programme jeweils ihren eigenen Adressraum haben. Andere Systeme erforderten, dass Programme "sich selbst verlagern", damit sie irgendwo im Speicher ausgeführt werden können und nicht mit einer bestimmten Adresse "verknüpft" werden.

Early Unix (unter anderem) handhabte den Multiprogramming-Job durch "Vertauschen" von Programmen: Ein Programm (geladen bei Adresse Null) würde so lange ausgeführt, bis es "blockiert" wird, um E / A zu erledigen, dann würde es "vertauscht" werden (in seinem Vollständig, einschließlich aller Codes und Daten) auf die Festplatte und ein anderes Programm "getauscht".

Zum größten Teil haben sich diese Techniken jedoch langsam zu verschiedenen Formen von Page-Mapping-Speichermodellen weiterentwickelt (oder vielleicht sogar weiterentwickelt).


Vielen Dank! Ich frage mich, wie sich das ausgelagerte Modell vom segmentierten Modell und vom flachen Modell unterscheidet.
Tim

Hat das ausgelagerte Modell nichts mit dem Auslagern zwischen Hauptspeicher und Festplatte im virtuellen Speicher zu tun?
Tim

AFAIK Windows 3.x und 9x tauschen auch das gesamte Programm aus. Paging zu diesem Zeitpunkt ist auf Windows NT begrenzt
phuclv

3

Ich bin ein Programmierer, aber kein eingebetteter Programmierer, der sich tatsächlich mit Speichermodellen auf dieser Ebene befassen muss. Nehmen Sie also, was ich sage, mit einem Körnchen Salz.

Nach meinem Verständnis werden Speichermodelle von der Prozessorarchitektur bestimmt. Sie sind am relevantesten für Programmierer, die mit Baugruppen, C auf niedriger Ebene oder allem, was der Hardware nahe kommt, arbeiten. Bei vielen höheren Sprachen wie Java oder C # gibt es Abstraktionen, die solche Details vor Ihnen verbergen, sodass Sie normalerweise nicht über Hardwarespeichermodelle nachdenken müssen.

Es gibt komische Zeiten, in denen es auftaucht. Ich verstehe, dass 32-Bit-x86-Prozessoren (zumindest in den letzten zehn Jahren) über Segmente ( PAE-Modus ) auf mehr als 4 GB Speicher zugreifen können. Viele 32-Bit-Betriebssysteme unterstützen dies, aber dann die maximale Speicherkapazität eines einzelnen Der Prozess, den Sie verwenden können, ist auf 4 GB beschränkt, da die meisten Programme ein flaches Speichermodell erwarten (und ich bezweifle, dass viele moderne Betriebssysteme es ihnen erlauben würden, etwas anderes zu erwarten).

So klären Sie die Anführungszeichen:

  1. Frühe x86-Prozessoren hatten ein Speichermodell, das einem Satz nummerierter Schubladen mit kleineren nummerierten Fächern ähnelte. Um auf ein bisschen Speicher zuzugreifen, müssen Sie die Schubladennummer zusammen mit der Fachnummer angeben. Alle Schubladen waren gleich, einige Programmierer entschieden sich nur für eine Schublade für Code, eine andere für Daten usw., aber diese Entscheidungen wurden nicht von der Prozessorarchitektur vorgegeben. Ein flaches Speichermodell hat genau eine Schublade, Sie verwenden also nur die Fachnummer.

  2. Ohne zusätzliche Funktionen (die verhindern, dass ein Programm den Speicher eines anderen Programms verwendet) ist ein flaches Speichermodell für moderne Betriebssysteme nicht geeignet, aber alle modernen Desktop- / Server-Prozessoren verfügen über diese Funktionen seit Jahrzehnten.

  3. Alle x86-Prozessoren verfügen über Modi, die aus Gründen der Abwärtskompatibilität wie 8086, 80286 usw. auf den Speicher zugreifen, sind jedoch veraltet. Praktisch niemand benutzt sie mehr und sie wechseln immer zu moderneren Modi.

Hoffe das hilft.


Vielen Dank! (1) Meinen Sie in 2 und 3, dass die meisten modernen Architekturen standardmäßig ein flaches Modell mit Rückkompatibilität zum segmentierten Modell verwenden, da moderne Prozessoren meistens über die Funktionen für den Speicherschutz verfügen? Wenn Sie beispielsweise in C auf modernem x86 programmieren, werden alle Zeiger standardmäßig mit dem flachen Modell von GCC implementiert, während die Verwendung des segmentierten Modells nicht der Standard ist. (2) Beeinflusst das Betriebssystem das zu verwendende Modell? In dem Zitat "Linux verwendet z. B. ein flaches Speichermodell" scheinen einige andere Betriebssysteme (vielleicht Windows, Mac) möglicherweise ein segmentiertes Modell zu verwenden.
Tim

@Tim Die Funktionen für die Abwärtskompatibilität werden vom Betriebssystem verwendet, wenn überhaupt. Moderne Betriebssysteme lassen nicht nur Programme in diese Modi gehen, da sie das gesamte System stören.
SysAdmin1138

1

Speichersegmentierung ist die Aufteilung des Hauptspeichers des Computers in Segmente oder Abschnitte. Segmente oder Abschnitte werden auch in Objektdateien kompilierter Programme verwendet, wenn sie zu einem Programmbild verknüpft sind oder wenn das Bild in den Speicher geladen wird. In einem Computersystem, das Segmentierung verwendet, enthält eine Referenz auf einen Speicherort einen Wert, der ein Segment und einen Versatz innerhalb dieses Segments identifiziert. Unterschiedliche Segmente können für unterschiedliche Programmmodule oder für unterschiedliche Klassen der Speichernutzung wie Code- und Datensegmente erstellt werden. Bestimmte Segmente können sogar von Programmen gemeinsam genutzt werden

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.