Dynamisch gelinkte Programme: entry? return?

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
Antworten
Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Dynamisch gelinkte Programme: entry? return?

Beitrag von Jside » So Jul 19, 2009 4:30 pm

Mal eine Frage, ich bastle zurzeit an meiner CPU Architektur weiter, aber wie genau funtioniert das nun mit dynamisch gelinkten Programmen? Daher wenn ich ein Programm habe, das z.b. die printf Funktion aufruft, woher weiß nun das Program, das der entry von printf bspw an 0x80004000 und nicht an 0x80100000 liegt? Wie funktioniert sowas? hab ich nochnie so richtig drüber nachgedacht...

Noch eine Frage: Wie sieht das nun aus, wenn der CPU z.b. eine Funktion aufruft, woher weiß der CPU das er beim Return wieder bei z.b. 0x2(siehe Beispiel) fortfahren soll, nunja wenn nur eine Funktion aufgerufen wird kein Problem, aber wann gibt es denn schonmal eine Funktion, die keine weiteren funktionen benutzt?

0x0: sw "hallo", 0x3 //Store Word
0x1: jump 0x4
0x2: //hier soll es weiter gehen
[...]

0x3: <.text>
0x4: lw 0x3, $t2 //Load Word
0x5: bw bd, $t2 //Value auf Datenbus legen
0x6: bw ba, 0x0011 //Serial Terminal Register mit Inhalt des Datenbusses füllen..
0x7: ret //Und wie komme ich nun wieder zu 0x2 ohne zu wissen, das es auf 0x2 weitergeht?

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3123
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Dynamisch gelinkte Programme: entry? return?

Beitrag von cloidnerux » So Jul 19, 2009 4:53 pm

woher weiß der CPU das er beim Return wieder bei z.b. 0x2(siehe Beispiel) fortfahren soll
Die ASm "ret" anweisung wird beim compilieren als eine art "jmp" befehl an den vorherigen sprungort zurücksrpingt.
woher weiß nun das Program, das der entry von printf bspw an 0x80004000 und nicht an 0x80100000 liegt?
Jedes Programm bekommt eine eigene pagedir, womit jedes Programm bei 0x00 Startet.
Damit ist es unötig, refernzen zu manipulieren.
Redundanz macht wiederholen unnötig.
quod erat expectandum

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Dynamisch gelinkte Programme: entry? return?

Beitrag von Dirty Oerti » So Jul 19, 2009 10:19 pm

Das Programm muss nicht wissen, wo genau im Speicher die Funktion (z.B. printf) liegt. Zumal jedes Programm seine eigene "Ansicht" des Speichers in Form von virtuellem Speicher besitzt.
printf, also der Zugriff auf eine Ressource, muss vom Betriebssystem verwaltet werden.

Im Endeffekt passiert folgendes:

Das Programm möchte Daten ausgeben. Dazu schickt es eine "Nachricht" an das Betriebssystem, einen sog. System Call. Dieser ist (eigntl immer) durch Interrupts möglich gemacht.
Das Programm verursacht nun also einen Interrupt, z.B. 0x80 (bei Linux..)

Code: Alles auswählen

int 0x80
In gewissen (vom Betriebssystem festzulegenden) Registern werden nun die Information, wie z.B. die Adresse des auszugebenden Strings gespeichert.
Das Betriebssystem übernimmt nach der INT-Anweisung die Kontrolle, liest das Register aus und führt dann die richtigen Operationen durch.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Dynamisch gelinkte Programme: entry? return?

Beitrag von Xin » Mo Jul 20, 2009 10:20 am

Jside hat geschrieben:Noch eine Frage: Wie sieht das nun aus, wenn der CPU z.b. eine Funktion aufruft, woher weiß der CPU das er beim Return wieder bei z.b. 0x2(siehe Beispiel) fortfahren soll, nunja wenn nur eine Funktion aufgerufen wird kein Problem, aber wann gibt es denn schonmal eine Funktion, die keine weiteren funktionen benutzt?

0x0: sw "hallo", 0x3 //Store Word
0x1: jump 0x4
0x2: //hier soll es weiter gehen
Eine (moderne) CPU hat ein Stack register.

Du packst entweder die Argumente der Funktion in die dafür vorgesehenen CPU Register oder Du wirft sie auf den Stack. Die Rücksprungadresse legst Du ebenfalls auf dem Stack, anschließend rufst Du die Funktion auf. Call oder Jsr (Jump To Subroutine) tun diesen Job für Dich. Return nimmt dann die Rücksprungadresse vom Stack (und ggfs. die nicht mehr benötigten Parameter) und springt an die Adresse, die auf dem Stack hinterlegt war.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Jside
Beiträge: 377
Registriert: Di Nov 11, 2008 12:56 am

Re: Dynamisch gelinkte Programme: entry? return?

Beitrag von Jside » Mo Jul 20, 2009 11:49 am

Dirty Oerti hat geschrieben:Das Programm muss nicht wissen, wo genau im Speicher die Funktion (z.B. printf) liegt. Zumal jedes Programm seine eigene "Ansicht" des Speichers in Form von virtuellem Speicher besitzt.
printf, also der Zugriff auf eine Ressource, muss vom Betriebssystem verwaltet werden.

Im Endeffekt passiert folgendes:

Das Programm möchte Daten ausgeben. Dazu schickt es eine "Nachricht" an das Betriebssystem, einen sog. System Call. Dieser ist (eigntl immer) durch Interrupts möglich gemacht.
Das Programm verursacht nun also einen Interrupt, z.B. 0x80 (bei Linux..)

Code: Alles auswählen

int 0x80
In gewissen (vom Betriebssystem festzulegenden) Registern werden nun die Information, wie z.B. die Adresse des auszugebenden Strings gespeichert.
Das Betriebssystem übernimmt nach der INT-Anweisung die Kontrolle, liest das Register aus und führt dann die richtigen Operationen durch.
Ähm Systemcalls sind doch dafür da, das Programme in höheren Ringen mit dem Kernel Ring kommunizieren können, die Libs laufen doch auf der Benutzterebene??
Xin hat geschrieben:Eine (moderne) CPU hat ein Stack register.

Du packst entweder die Argumente der Funktion in die dafür vorgesehenen CPU Register oder Du wirft sie auf den Stack. Die Rücksprungadresse legst Du ebenfalls auf dem Stack, anschließend rufst Du die Funktion auf. Call oder Jsr (Jump To Subroutine) tun diesen Job für Dich. Return nimmt dann die Rücksprungadresse vom Stack (und ggfs. die nicht mehr benötigten Parameter) und springt an die Adresse, die auf dem Stack hinterlegt war.
Mhm das klingt ganz gut, lässt sich auch vergleichsweise leicht implentieren, werde ich mal einbauen...

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Dynamisch gelinkte Programme: entry? return?

Beitrag von Dirty Oerti » Mo Jul 20, 2009 11:58 am

Jside hat geschrieben:Ähm Systemcalls sind doch dafür da, das Programme in höheren Ringen mit dem Kernel Ring kommunizieren können, die Libs laufen doch auf der Benutzterebene??
Ja, genau dafür sind sie da. Aber der Zugriff auf eine Ressource (Bildschirm) erfordert, das der Kernel "zustimmt".
Die printf Funktion, die sich im Userspace befindet, kümmert sich "nur" um einen korrekten Aufruf des Systemcalls, der wiederum das eigentliche Schreiben übernimmt (bzw Anordnet).
Die printf-Funktion im Userspace wird vom Linker eben an einen gewissen Platz gelegt (alle Sprungadressen werden eben so eingetragen), und dorthin dann beim Start eines Programmes vom Betriebssystem gemappt.

So liegt der Code für die (Userspace)printf-Funktion z.B. bei der Hardwareadresse 0x1000 und wird dann für das Programm Xy in desen virtuellen Speicher an 0x4000 gemappt (also nicht kopiert, ein Zugriff des Programms an virtueller Adresse 0x4000 resultiert in einem Zugriff an der Hardwareadresse 0x1000). Für ein anderes Programm könnte diese virtuelle Adresse auch z.B. 0x5000 sein.
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Antworten