Je doute vraiment que le compilateur sait qu'il s'agit d'un appel système. Il est beaucoup plus probable que open
se trouve dans une bibliothèque quelque part et le code dans la bibliothèque appelle l'interface de noyau appropriée.
La sortie de montage du programme simple:
#include <stdio.h>
int main (void) {
int fd = open("xyz");
return 0;
}
est (bits non pertinents supprimés):
main:
pushl %ebp ; stack frame setup.
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $.LC0, (%esp) ; Store file name address.
call open ; call the library function.
movl %eax, 28(%esp) ; save returned file descriptor.
movl $0, %eax ; return 0 error code.
leave ; stack frame teardown.
ret
.LC0:
.string "xyz" ; file name to open.
La première chose que vous remarquerez est qu'il ya un appel-open
. En d'autres termes, c'est une fonction. Il n'y a pas un int 80
ou sysenter
en vue, qui est le mécanisme utilisé pour les appels système appropriés (sur ma plate-forme de toute façon - YMMV).
Les fonctions d'encapsulation dans libc sont celles où le travail réel d'accès à l'interface d'appel système est effectué.
Un extrait de Wikipedia sur system calls:
fournissent généralement, des systèmes de la bibliothèque qui se trouve entre les programmes normaux et le système d'exploitation, généralement une mise en oeuvre de la bibliothèque C (libc), tels que glibc. Cette bibliothèque existe entre le système d'exploitation et l'application et augmente la portabilité.
Sur les systèmes basés sur exokernel, la bibliothèque est particulièrement importante en tant qu'intermédiaire. Sur les exokernels, les bibliothèques protègent les applications utilisateur de l'API de noyau de très bas niveau et fournissent des abstractions et une gestion des ressources. Les termes «appel système» et «appel système» sont souvent utilisés de manière incorrecte pour désigner les fonctions de bibliothèque standard C, en particulier celles qui servent d'encapsuleur aux appels système correspondants portant le même nom. L'appel à la fonction bibliothèque elle-même n'entraîne pas de basculement vers le mode noyau (si l'exécution n'était pas déjà en mode noyau) et est généralement un appel de sous-routine normal (par exemple, une instruction d'assemblage "CALL" dans certains ISA). L'appel système réel transfère le contrôle au noyau (et est plus dépendant de l'implémentation que l'appel de la bibliothèque l'abstrayant). Par exemple, fork
et execve
sont des fonctions GLIBC qui appellent à leur tour les appels système fork
et execve
.
Et, après un peu de recherche, la fonction __open
se trouve dans la glibc 2.9 dans le fichier io/open.c
et weakref
« ed à open
.Si vous exécutez:
nm /usr/lib/libc.a | egrep 'W __open$|W open$'
vous pouvez les voir là-dedans:
00000000 W __open
00000000 W open
ouvert est également un appel système. Il n'y a pas de code à ouvrir dans une bibliothèque. Comment le compilateur résout pour l'appel ouvert? –
Pas ainsi, voir la mise à jour. – paxdiablo
Disons, j'ai inséré mon propre appel système et compilé le noyau qui n'a pas de fonction wrapper dans libc. –