Seite 1 von 1

Dynamisch gelinkte Programme: entry? return?

Verfasst: So Jul 19, 2009 4:30 pm
von Jside
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?

Re: Dynamisch gelinkte Programme: entry? return?

Verfasst: So Jul 19, 2009 4:53 pm
von cloidnerux
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.

Re: Dynamisch gelinkte Programme: entry? return?

Verfasst: So Jul 19, 2009 10:19 pm
von Dirty Oerti
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.

Re: Dynamisch gelinkte Programme: entry? return?

Verfasst: Mo Jul 20, 2009 10:20 am
von Xin
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.

Re: Dynamisch gelinkte Programme: entry? return?

Verfasst: Mo Jul 20, 2009 11:49 am
von Jside
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...

Re: Dynamisch gelinkte Programme: entry? return?

Verfasst: Mo Jul 20, 2009 11:58 am
von Dirty Oerti
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.