"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Comprensión de los tiempos de ejecución: de C a los lenguajes modernos

Comprensión de los tiempos de ejecución: de C a los lenguajes modernos

Publicado el 2024-11-08
Navegar:880

Understanding Runtimes: From C to Modern Languages

En la era del desarrollo y la programación de software modernos, el término "tiempo de ejecución" puede significar diferentes cosas según el contexto y el lenguaje que se esté analizando. Estoy aquí para aclarar estas diferencias, centrándome en cómo funcionan los tiempos de ejecución en C en comparación con lenguajes más modernos como Java o Python. Tengo la intención de mantener este artículo enfocado a programadores principiantes, por lo que evitaré profundizar en conceptos complejos.

¿Qué es un tiempo de ejecución?

En esencia, un tiempo de ejecución es un programa en sí mismo que lee y ejecuta código escrito por un desarrollador. Pero resulta confuso cuando algunos desarrolladores usan el tiempo de ejecución con lenguaje C.

Tiempos de ejecución del lenguaje moderno

En lenguajes como Java o Python, el tiempo de ejecución es un programa en sí mismo que lee su archivo myfile.js, es por eso que ejecuta programas nodejs como: node myfile.js y el motor v8 (es el motor de JavaScript, analiza y ejecuta JavaScript code.) administra todo, ya sea que cree un nuevo archivo, active un proceso secundario, etc., y lo más importante es que no puede hacer nada que v8 no le permita hacer.
Pero cuando ejecutas un programa en C, no haces c myfile.c, solo tienes que compilarlo una vez y ahora ya no necesitas gcc, solo ejecútalo directamente.

El "tiempo de ejecución" de C

En C, no hay un programa separado que se ejecuta junto con su código de la misma manera que en Java o Python. En cambio, lo que a menudo se llama "tiempo de ejecución" de C es en realidad un conjunto de código insertado estáticamente e instrucciones agregadas durante la compilación. Es un conjunto mínimo de instrucciones incluidas en el binario final para manejar ciertas tareas necesarias a nivel de CPU/OS. Maneja la creación y desmontaje de marcos de pila para llamadas a funciones (usando instrucciones como PUSH, POP, CALL, RET en ensamblaje). Incluso eso se puede anular proporcionando su propia función __start usando un ensamblado en línea, brindando a los desarrolladores control total sobre el punto de entrada y la inicialización del programa.


void __start() {
// Custom entry point, no standard library initialization
// You have no access to argc and argv here unless you access them manually from registers
// you can create you own custom stack setup, initialization and etc here.

// Exit directly using a syscall
asm("mov $60, %rax; mov $0, %rdi; syscall"); // exit(0) syscall
}


Esto no parece tiempo de ejecución en absoluto, es solo un código en lenguaje ensamblador agregado por el compilador para que los desarrolladores no tengan que hacerlo.

El poder y la responsabilidad de C

En C, puedes invocar llamadas al sistema directamente usando un ensamblado en línea para interactuar con el kernel en formas que normalmente no permiten el sistema operativo, así es como se crean los malwares. El ensamblador en línea permite a los desarrolladores escribir instrucciones en lenguaje ensamblador dentro del código C. Esto se utiliza a menudo para código crítico para el rendimiento o para acceder a funciones de hardware específicas.

Ensamblaje en línea en C

  • El ensamblaje en línea permite a los desarrolladores escribir instrucciones en lenguaje ensamblador dentro del código C. Esto se utiliza a menudo para código crítico para el rendimiento o para acceder a funciones de hardware específicas.
  • Proporciona una forma de ejecutar instrucciones de la CPU directamente.

Interacción directa con el kernel

  • Al utilizar el ensamblado en línea, un programador puede invocar llamadas al sistema directamente sin pasar por bibliotecas de nivel superior.
  • Por ejemplo, podemos usar un ensamblado en línea para configurar registros con los parámetros apropiados para una llamada al sistema y luego activarlo.
  • Dado que el ensamblaje en línea permite un control de bajo nivel sobre los recursos del sistema, se puede utilizar para eludir los mecanismos de seguridad o manipular el kernel directamente. Así es como el malware puede realizar acciones no autorizadas, como acceder a la memoria protegida, interceptar llamadas al sistema o manipular procesos y su memoria.
  • El malware puede explotar vulnerabilidades en el sistema operativo o utilizar estas interacciones de bajo nivel para realizar tareas como registro de teclas, escalada de privilegios u operaciones sigilosas.

En Linux C tiene un FLAG que le permite escribir datos de archivos directamente en un dispositivo de almacenamiento, sin pasar por algunos de los mecanismos de almacenamiento en caché del kernel, se llama indicador O_DIRECT que se usa en combinación con las llamadas al sistema de apertura y escritura. Este indicador garantiza que los datos no se almacenen en la RAM ni sean administrados por el kernel en el espacio del kernel; esto escribe directamente los datos en el disco duro, JVM no le permitirá hacerlo, y es solo un ejemplo simple.
aquí hay un ejemplo simple:


asm volatile (
"syscall"
: "=a" (written)
: "0" (1),
"D" (fd),
"S" (buffer),
"d" (BLOCK_SIZE)
: "rcx", "r11", "memory"
);


*Nota: * (escrito) es una variable creada dentro de main(), (1) es el número de llamada al sistema para escritura, (fd) es donde se escribirá el archivo, es decir, int fs = open("ruta .log",O_WRONLY; (BLOCK_SIZE) es otro nombre de variable. Es más complejo que eso.

La evolución de los tiempos de ejecución

Es importante comprender que el concepto de tiempo de ejecución ha evolucionado a lo largo de los años. El "tiempo de ejecución" de C de los años 70 es muy diferente de los entornos de ejecución robustos que vemos en los lenguajes de la década de 2000. Esta evolución puede generar confusión cuando se habla de tiempos de ejecución, especialmente entre desarrolladores familiarizados con diferentes épocas de programación.

Conclusión

Creo que la gente ahora está comparando el tiempo de ejecución de la década de 1970 con el de la década de 2000, lo que está confundiendo a los nuevos desarrolladores con los antiguos.
Resolver un problema específico es la tarea principal de cualquier lenguaje de programación; no desea escribir un marco completo para crear API en C. Tenemos nodejs y es bueno en eso y no necesita escribir código básico en javascript porque Ya tengo C y es fabuloso en eso. ¿Por qué reinventar la rueda? Usemos las ruedas y creemos un automóvil fabuloso, a menos que no quieras conducirlo en Marte.

Declaración de liberación Este artículo se reproduce en: https://dev.to/bossysmaxx/understanding-runtimes-from-c-to-modern-languages-3fkj?1 ​​​​Si hay alguna infracción, comuníquese con [email protected] para eliminarla. él
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3