Forum: PC Hard- und Software Woher weiß die CPU die Adressen der RAM-Speicherstellen?


von Cat C. (catcache)


Lesenswert?

Woher weiß die CPU, wo sie den nächsten Befehl aus dem RAM holen muss? 
In einem Buch zu Rechnerarchitektur steht, dass die CPU die Adresse halt 
zum RAM schickt und dann daraus die Daten ließt.
Ich habe aber mal irgendwo gelesen, dass die Adressen beim 
Compelier-Vorgang des Quellcodes schon festgelegt werden. Daher würde 
ich eigentlich sagen, dass das compelierte Programm der CPU die Adressen 
mitteilt oder liege ich da falsch?

LG

von (prx) A. K. (prx)


Lesenswert?

Cat C. schrieb:
> Woher weiß die CPU, wo sie den nächsten Befehl aus dem RAM holen muss?

Es gibt ein Register für die Adresse des Befehls, den Program Counter. 
Wenn ein Befehl nicht grad ein ausgeführter Sprungbefehl ist, dann zählt 
dieses Register einfach hoch.

von HVV (Gast)


Lesenswert?

Cat C. schrieb:
> Woher weiß die CPU, wo sie den nächsten Befehl aus dem RAM holen muss?
Jede Instruktion hat eine bestimmte länge NOP (No OPeration) z.B. ein 
Byte, also wird der IP (Instruction Pointer _ Befehlszeiger) um ein Byte 
inkrementiert.

> In einem Buch zu Rechnerarchitektur steht, dass die CPU die Adresse halt
> zum RAM schickt und dann daraus die Daten ließt.
richtig.

> Ich habe aber mal irgendwo gelesen, dass die Adressen beim
> Compelier-Vorgang des Quellcodes schon festgelegt werden. Daher würde
> ich eigentlich sagen, dass das compelierte Programm der CPU die Adressen
> mitteilt oder liege ich da falsch?
>
> LG

Falschder Compiler/Assembler erzeug Objekt Code, die Instrutionen sin 
schon in Binaer übersetzt, die Addressen sind noch nicht exakt 
festgelegt, werden sie auch nicht wirklich, denn weder 
Compiler/Assembler noch Windows/Linux wissen vor Programmstart wo diese 
exakt liegen werden. der Relocator (Teil des Linkers berechnet vor dem 
Linken den Addressofste der Programmteile, bei einer .exestartet das 
eigentliche Programm nach dem Header das sieht dann z.B. so aus:

0000 jump 0x0100 ;Sprung zum Programmstart
0001 MZ ; Microsoft Identifier für .exe
.... zum Aufbau des Headers bitte Wikipedia o.ä. nutzen
0100 'Do Something' ; Programmstart

von (prx) A. K. (prx)


Lesenswert?

Cat C. schrieb:
> ich eigentlich sagen, dass das compelierte Programm der CPU die Adressen
> mitteilt oder liege ich da falsch?

In einem Programm ist festgelegt, an welcher Stelle es beginnt. Den Weg 
ab dieser Adresse findet die CPU dann, indem sie einen Befehl nach dem 
anderen ausführt.

Bei einem Programm ohne Betriebssystem, etwa einem Mikrocontroller, 
fängt ein Programm per Definition des Herstellers immer an einer festen 
Adresse an, z.B. 0. Der Compiler baut das Programm dementsprechend auf.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Es wäre besser, sich das auf einem µC anzuschauen als auf einem PC, da 
es da dann doch etwas komplizierter ist aufgrund von BIOS und 
Betriebssystem und Speichervirtualisierung, dynamischer Bibliotheken 
u.s.w.

von Georg (Gast)


Lesenswert?

Cat C. schrieb:
> Daher würde
> ich eigentlich sagen, dass das compelierte Programm der CPU die Adressen
> mitteilt oder liege ich da falsch?

Ja, das ist falsch ausser auf dem primitivst-möglichen System. Die 
Adresse "entsteht" in realen Systemen in mehreren Stufen:

1. Der Compiler legt fest, wie lang ein Befehl ist, also wieviel 
Speicherplätze er belegt, und erzeugt ein Object-Modul, in dem für jeden 
Befehl der entsprechende Platz reserviert ist.

2. Der Linker ordnet alle Module im Speicher an und legt danach die 
absolute Adresse fest, wenn es sich um ein einfaches Controller-System 
handelt. Dieser Code steht fest im Programmspeicher und beginnt am 
Resetvektor, meistens die Adresse 0. Für ein komplexes Betriebssystem 
erzeugt er keinen absoluten Code, sondern "relocatable" Code (EXE,elf).

ab hier nur Windows/Linux usw.
3. Der Programmlader lädt den Code an eine freie Stelle ins RAM, dann 
geht der Relocator drüber und passt alle Adressen wie Sprungziele an den 
tatsächlichen Speicherplatz an.

4. Bei virtuellem Memory ist Relozieren nicht nötig, jeder Prozess kann 
an der gleichen Adresse beginnen, die Memory Unit mappt das jeweils auf 
einen anderen tatsächlichen Speicherbereich.

5. Weil es sicherheitstechnisch ungünstig ist, wenn der Speicherbereich 
bekannt ist, weil alle den gleichen benutzen, gibt es die Möglichkeit, 
jeden Prozess auf einen anderen zufälligen Bereich zu relozieren, das 
erschwert die Ausnutzung von Schwachstellen.

Wie auch immer, ist ein Befehl z.B. 4 Bytes lang, so ist die Adresse des 
nächsten Befehls eben 4 Bytes weiter im Programmspeicher. Ist 
stattdessen ein Sprung erforderlich, wird die Zieladresse aus dem 
Programmspeicher gelesen, sie ist nämlich Bestandteil des aktuellen 
Befehls.

Georg

von HVV (Gast)


Lesenswert?

Georg schrieb:
> dann
> geht der Relocator drüber und passt alle Adressen wie Sprungziele an den
> tatsächlichen Speicherplatz an.

Nein, die Sprünge (JNZ, JGE...) und JMP und CALL sind (x86) per default 
relativ, nur far call / far jump sind ohne weitere spezifizierung 
absolut.

von Christian M. (Gast)


Lesenswert?

Dann gibt's noch die PC-relative Programmierung, bei der jeder Variablen 
noch der PC (Programm Counter) dazu addiert. Dann kann das Programm an 
jeder Speicherstelle stehen, wo es will.

Gruss Chregu

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.