Ein Systemaufruf ruft Betriebssystemfunktionen auf. Betriebssystemfunktionen sind Bestandteil der Kernels.
Systemaufrufe rufen sog. privilegierte Funktionen auf, die ein Benutzerprogramm nicht ausführen dürfte. Deshalb muss der Zugriff darauf genau kontrolliert werden.
Systemaufrufe werden normalerweise als Software-Interrupts implementiert.
Der i386 bietet hierbei eine Zugriffskontrolle über Interrupt-Gates.
Die tatsächliche Sprungadresse bleibt dem Programm verborgen, d.h. sie
kann sich auch ändern.
Beim i386 wäre auch eine Lösung über Call-Gates möglich.
Die Beendigung eines Prozesses incl. dem Bereinigen der internen
Datenstrukturen und der Rückkehr in den aufrufenden
Prozess sind privlegierte Operationen. Würde der Prozess sich durch
ein einfaches return 0;
beenden können, müsste dazu
die Rücksprungadresse auf dem Stack liegen und könnte daher
manipuliert werden.
Unterprogramme werden mit dem Assemblerbefehl call
(i386)
aufgerufen.
Programme werden mit den Systemaufrufen
fork()/execve()
(Unix) bzw. CreateProcess
(Windows) gestartet. Das Programm muss geladen werden, der Stack
initialisiert werden usw.
Progr. 1 ----------- char buf[50000] = "0"; int main() { return 0; } -------------------- Progr. 2 ----------- int main() { char buf[50000] = "0"; return 0; }
In Progr. 1 wird buf
im zur Kompilierzeit Datenspeicher
angelegt, in Progr. 2 dagegen zur Laufzeit auf dem Stack.
insgesamt 88 -rwxr-xr-x 1 cjw users 61711 Mär 25 16:14 n6-1 -rw-r--r-- 1 cjw users 49 Mär 25 16:13 n6-1.cc -rwxr-xr-x 1 cjw users 11813 Mär 25 16:14 n6-2 -rw-r--r-- 1 cjw users 51 Mär 25 16:14 n6-2.cc
main
den Typ int
haben. Sie kann einen Int-Wert zurückgeben, muss aber nicht. Ein
fehlendes return
in main
entspricht nach
C++-Sprachstandard einem return 0;
. Stellen Sie fest, ob der
GNU-Compiler sich entsprechend verhält. Übersetzen Sie dazu
Testprogramme mit der Option -S in Assemblercode.
---- schnipp ---- main: .LFB1: pushl %ebp .LCFI0: movl %esp,%ebp .LCFI1: xorl %eax,%eax // eax = rückgabewert wird auf null gesetzt jmp .L2 .p2align 4,,7 .L2: movl %ebp,%esp popl %ebp ret ---- schnapp ----
main
-Funktion eines C/C++-Programms
zurück? Ins Betriebssystem? Was genau ist der Unterschied zwischen
return 0;
, exit(0);
und _exit(0);
?
main()
wird nicht vom Betriebssystem aufgerufen, sondern von
einer Initialisierungsroutine im Programm. Das Betriebssystem springt an das
Label _start
. main()
kehrt in die
Initilisierungsroutine zurück, die _exit()
aufruft.
return 0;
exit(0);
ruft die exit-Funktion der C-Library auf. Die ruft
atexit()
auf, schliesst noch offene Dateien und ruft dann
_exit()
auf.
_exit()
ist der Systemaufruf.