Wie funktioniert die virtuelle Addressvergabe bei heutigen Systemen



  • Ist damit gemeint,dass im fertig kompilierten Programm immernoch einfach nur der Name der Variablen steht und das OS ordnet den Namen dann erst beim Start des Programms die logischen Adressen zu,oder was ist mit relativ gemeint?


  • Mod

    MemoryManagment schrieb:

    Ist damit gemeint,dass im fertig kompilierten Programm immernoch einfach nur der Name der Variablen steht und das OS ordnet den Namen dann erst beim Start des Programms die logischen Adressen zu,oder was ist mit relativ gemeint?

    Nein, überhaupt gar nicht. Du scheinst eine völlig falsche Vorstellung zu haben, wie ein Maschinensprachenprogramm funktioniert. Variablen existieren gar nicht mehr und erst recht nicht ihre Namen. Ich denke nicht, dass ich das im Rahmen eines Forenbeitrags erklären kann, außer mit Phrasen wie "alles, an was du glaubst, ist eine Lüge" oder "vergessen du musst, was früher du gelernt hast". Es macht auch nicht viel Sinn, eine Antwort auf deine erste Frage zu versuchen, du würdest sie nicht verstehen.

    Lern mal die Grundlagen von Assembler (ist so nah an der Maschinensprache, dass man von einer 1:1 Übersetzung reden kann, bloß eben für Menschen lesbar), egal für welche Maschine. Dann guck dir vielleicht mal an, was dein Compiler aus einem einfachen Testprogramm macht (viele Compiler können Assembler als Zwischenschritt ausgeben oder zur Not übersetzt man das fertige Programm zurück). Dann bist du so weit, dass du eine Antwort verstehen würdest. Aber höchstwahrscheinlich hat sich die Frage dann ganz von selbst erledigt, denn die Antwort ist (mit diesem Hintergrundwissen) unmittelbar offensichtlich.



  • Hast du denn eine Empfehlung für Assembly Lektüre?
    Das ein Name selbst nichtmehr existiert ist klar der der würde natürlich nach dem Compilen nurnoch aus einer Bitcodierung bestehen,das OS könnte dieses Bitmuster dann aber auch wieder interpretieren das Meinte ich damit,dass in Binärcode keine Namen stehen ist mir bewusst 😃 das war etwas unglücklich formuliert.

    Ich würde das jetzt aber schon gerne verstehen,weil mich diese Frage schon eine ganze weile plagt.
    Was steht im kompilierten Quellcode (in Assembler ausgedrückt) wird einfach jeder Variablen beim Compilen ein Offset vergeben und beim start wird dieses Offset auch die Base des Prozesses addiert um die logische Adresse zu erhalten,oder wie?
    Ich verstehe eben nur nicht was du in diesem Zusammenhang mit relativ meinst.


  • Mod

    MemoryManagment schrieb:

    Hast du denn eine Empfehlung für Assembly Lektüre?

    Leider nein, hab das selber in der Schule gelernt.

    Das ein Name selbst nichtmehr existiert ist klar der der würde natürlich nach dem Compilen nurnoch aus einer Bitcodierung bestehen,das OS könnte dieses Bitmuster dann aber auch wieder interpretieren das Meinte ich damit,dass in Binärcode keine Namen stehen ist mir bewusst 😃 das war etwas unglücklich formuliert.

    Auch das ist eine völlig falsche Vorstellung. Es gibt keine Variablen. Variablen sind Elemente von Hochsprachen, damit Menschen einfacher Programme schreiben können.

    Ich würde das jetzt aber schon gerne verstehen,weil mich diese Frage schon eine ganze weile plagt.

    Ich kann leider nicht den komplizierteren Fall (nicht, dass es wirklich kompliziert wäre, bloß komplizierter) erklären, wenn dir nicht einmal im Ansatz klar ist, was der Normalfall ist.



  • SeppJ schrieb:

    Auch das ist eine völlig falsche Vorstellung. Es gibt keine Variablen. Variablen sind Elemente von Hochsprachen, damit Menschen einfacher Programme schreiben können.

    Ist mir bewusst mit einer Definition einer Variablen gibt man dem Rechner nur an lege X bit/Byte in einen Speicherberreich an und Adressiere mir diesen.
    Wie die Bits/Bytes später interpretiert werden sollen hängt vom Programmierer ab das bestimmt er mit dem Typ einer Variablen....

    Könntest du mir nicht einfach ein kurzes Beispiel geben,oder erläutern was du mit relativer Adressangabe meintest.
    Wenn ich es nicht verstehen sollte Ok dann lass ich das Thema halt erstmal links liegen,aber im moment interessiert mich das schon sehr.



  • Ergänzung des vorigen posts:
    Bei der Definition legt man natürlich nichts an hatte ich wieder blöd ausgedrückt ,sondern man reserviert den Speicherberreich.Bei der Initialisierung wird ein bestimmtes Bitmuster erzeugt welches dann in diesen Speicherberreich geschrieben wird.(Nur damit ich nicht falsch verstanden werde).
    Ich weiß ich drücke mich manchmal sehr unglücklich aus,aber nur zu schreiben alles was du denkst ist falsch ohne jede Erklärung hilft mit leider wenig weiter(No Offense 😃 ).


  • Mod

    MemoryManagment schrieb:

    Ist mir bewusst mit einer Definition einer Variablen gibt man dem Rechner nur an lege X bit/Byte in einen Speicherberreich an und Adressiere mir diesen.
    Wie die Bits/Bytes später interpretiert werden sollen hängt vom Programmierer ab das bestimmt er mit dem Typ einer Variablen....

    Eben auch nicht. Vielleicht in absichtlich unoptimierten Code, damit ein Debugger noch irgendwie einen Zusammenhang zwischen Speicherbereichen und Variablen im Quellcode herstellen kann.

    Könntest du mir nicht einfach ein kurzes Beispiel geben,oder erläutern was du mit relativer Adressangabe meintest.

    Na, relativ eben. Anstatt zu sagen "nimm den Wert an Adresse XYZ", sagt man "nimm den Wert an Stackpointer - 16". Und dieses "Anlegen" von Variablen ist dann das Verschieben des Stackpointers an eine andere Stelle, so dass vor dem Stackpointer genug Platz ist für die Variablen, die eine Funktion braucht. Und wenn die Funktion fertig ist, dann setzt sie den Zeiger wieder da hin, wo er vorher war, so dass die Funktion, aus der die erste Funktion her aufgerufen wurde, von all dem überhaupt gar nichts mitbekommt und ganz normal mit ihren "Variablen" weiter arbeiten kann.

    Obiges ist, wie lokale Variablen funktionieren. Wenn du das verstanden hast, dann bist du schon viel weiter. Guck mal hier:
    http://en.wikipedia.org/wiki/Call_stack



  • Danke für deine Erklärung das war jetzt auch verständlich für mich.
    Wenn der Prozess gestartet wird wird der StackPointer auf die erste Adresse gesetzt. Der Compiler wandelt beim Aufruf einer lokalen Variablen diese einfach um in (Adresse1+X) um.Das geht,weil die logischen Adressen in einem zusammenhängenden Speicherberreich liegen.Die Base wird ja eh immer vom Os bestimmt.Jetzt verstehe ich denke ich auch was mit relativ gemeint war in C++ kann man ja ebenfalls:

    int arr[10];
    int* p_arr=arr;
    *p_arr+5=10;
    

    schreiben.



  • Ach hatte noch was falsch verstanden der Compiler wandelt eine Variable nicht in um (adresse1+offset),sondern der Compiler errechnet wo der Stack Pointer jetzt grade steht und schreibt (Aktueller Stand des StackPointers +/- Offset) um auf die gewollte Adresse zu kommen.Man kann ja immer nur vom aktuellen Stand aus weiter/zurück gehen.


  • Mod

    Der Compiler ist nur bei der Übersetzung des Programmes aktiv.

    Der Stackpointer ist wirklich ein Wert, der irgendwo im Prozessor steht. Der Compiler rechnet, wenn er das Programm erstellt, aus, wie viel Platz eine Funktion braucht und erzeugt dann am Anfang des Codes der Funktion eine Anweisung, die den Stackpointer um eben diesen Betrag weiter setzt. Dann kann er für die Funktion Code erzeugen, der in eben diesem Bereich (zwischen alter Stackgrenze und neuer Stackgrenze) machen kann, was er will. An keiner Stelle müssen konkrete Werte für die Adressen bekannt sein.

    ~(Das ist in Wirklichkeit natürlich alles ein bisschen komplizierter (z.B. wie Rückgabewerte einer Funktion funktionieren), aber mit dieser Vorstellung kommt man schon recht weit.)~


  • Mod

    Für x86 und C habe ich den Mechanismus aufgezeigt: http://henkessoft.de/C/C-Programming Under The Hood.htm


Anmelden zum Antworten