Funciones como readdir()
y amigos se implementan en libc, que es una biblioteca compartida. Al igual que con todas las bibliotecas compartidas, eso agrega cierta redirección para poder resolver la dirección de memoria de la función dentro de la biblioteca compartida.
La primera vez que se realiza una llamada de biblioteca en particular, el enlazador dinámico necesita buscar la dirección de la llamada de biblioteca dentro de una tabla hash. Esto implica al menos una (pero posiblemente más )comparaciones de cadenas, un método comparativamente costoso. La dirección encontrada luego se guarda en la tabla de vinculación de procedimientosPLT
(), de modo que la próxima vez que se llame a la función, la sobrecarga de encontrar la función se reduce a tres instrucciones (en la arquitectura x86, menos que eso. en algunas otras arquitecturas ). Esta es la razón por la que compilar algo como un objeto compartido (en lugar de un objeto estático )tiene algunos gastos generales. Para obtener más información sobre la sobrecarga de bibliotecas compartidas y cómo funcionan las bibliotecas compartidas en Linux, consulte la explicación técnica detallada de Ulrich Drepper sobre el tema .
La función syscall()
en sí misma está también implementada en libc, por lo que también tiene esa redirección. Sin embargo, dado que solo usaría esa función (y ninguna otra ), el enlazador dinámico tiene menos trabajo que hacer. Además,la implementación de una función particular como readdir
tendría que convertir los valores devueltos y realizar una verificación de errores, etc. al salir de la función syscall()
, lo cual es una sobrecarga adicional. Un programa que se ejecuta syscall()
directamente funcionaría con los valores de retorno directos de la llamada al sistema y no necesitaría esa conversión (, aún necesitaría hacer la verificación de errores, lo que complicaría la función significativamente ).
La desventaja de ejecutar syscall()
directamente es que pasa a una API que es menos portátil. La página de manual syscall()
explica algunas limitaciones específicas de la arquitectura -que libc trata por usted; si usa syscall()
directamente, su función podría funcionar en la arquitectura con la que está tratando, pero fallaría, por ejemplo, en una máquina de brazo.
En general, recomendaría no usar la API syscall()
directamente, por la misma razón por la que recomendaría no escribir el código en lenguaje ensamblador directamente. Sí, eso podría terminar siendo más rápido al final, pero la carga de mantenimiento se vuelve (mucho )mayor. Algunas cosas que podrías hacer en su lugar:
gcc -static
)