¿Cómo se inicia un programa C?En C, ¿cómo se llama inicialmente el método main()?
Respuesta
Finalmente es el sistema operativo. Generalmente hay algún medio entre el punto de entrada real y la función principal, esto se inserta mediante el compilador
.
Algunos detalles (relacionados con Windows): Hay un encabezado en el archivo PE llamado IMAGE_OPTIONAL_HEADER
que tiene el campo AddressOfEntryPoint
, que a su vez es la dirección del primer byte de código en el archivo que se ejecutará.
No es insertado por el compilador, es insertado por el enlazador, usualmente enlazando a algo como 'crt.a (crt .o) 'o' crt.lib (crt.obj) ', que generalmente forma parte de algo como' libc.a' o 'c.lib'. –
@ChristianHujer tienes razón, por compilador quise decir bien la cadena de herramientas. – Andrey
estás seguro acerca de __linker__, supongo que qué __loader__ hace entonces? – roottraveller
El sistema operativo llama a la función main()
. En realidad, generalmente llama a algo más llamado algo extraño como _init
. El compilador de C vincula una biblioteca estándar a cada aplicación que proporciona este punto de entrada definido por el sistema operativo y luego llama al main()
.
Editar: Obviamente, eso no era lo suficientemente detallado y correcto para algunas personas.
El Executable and Linkable Format (ELF) que muchos sistemas operativos Unix definen como una dirección de punto de entrada. Ahí es donde el programa comienza a ejecutarse después de que el sistema operativo finaliza su llamada exec()
. En un sistema Linux esto es _init.
De -d objdump:
Disassembly of section .init:
08049f08 <_init>:
8049f08: 55 push %ebp
8049f09: 89 e5 mov %esp,%ebp
8049f0b: 83 ec 08 sub $0x8,%esp
8049f0e: e8 a1 05 00 00 call 804a4b4 <call_gmon_start>
8049f13: e8 f8 05 00 00 call 804a510 <frame_dummy>
8049f18: e8 d3 50 00 00 call 804eff0 <__do_global_ctors_aux>
8049f1d: c9 leave
8049f1e: c3 ret
De -d readelf:
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x8049f08
0x0000000d (FINI) 0x804f018
0x00000004 (HASH) 0x8048168
0x00000005 (STRTAB) 0x8048d8c
0x00000006 (SYMTAB) 0x804867c
0x0000000a (STRSZ) 3313 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000015 (DEBUG) 0x0
0x00000003 (PLTGOT) 0x8059114
0x00000002 (PLTRELSZ) 688 (bytes)
0x00000014 (PLTREL) REL
0x00000017 (JMPREL) 0x8049c58
0x00000011 (REL) 0x8049be0
0x00000012 (RELSZ) 120 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffe (VERNEED) 0x8049b60
0x6fffffff (VERNEEDNUM) 3
0x6ffffff0 (VERSYM) 0x8049a7e
0x00000000 (NULL) 0x0
Se puede ver que INIT es igual a la dirección de _init.
El código para frame_dummy y __do_global_ctors_aux está en un conjunto de archivos llamados crtbegin.o y crtend.o (y variantes de esos nombres). Estos son parte de GCC. Ese código hace varias cosas necesarias para un programa C, como la configuración de stdin, stdout, variables globales y estáticas y otras cosas.
El siguiente artículo describe bastante bien lo que hace en Linux (tomado de una respuesta más abajo con menos votos): http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html
creo que otra persona de respuesta ya se ha descrito lo que hace de Windows.
Tenga en cuenta que además de las respuestas ya publicado, también es posible que usted pueda llamar main
mismo. En general, esta es una mala idea reservada para el código ofuscado.
Esto no es legal en C++, por cierto, una forma más en la que C++ no es un superconjunto estricto. –
El sistema operativo se llama main. Habrá una dirección en el ejecutable reubicable que apunta a la ubicación de main (Ver el ABI de Unix para más información).
Pero, ¿quién llama al sistema operativo?
La unidad de procesamiento central, en la señal "RESET" (que también se activa al encender), comenzará a buscar en alguna ROM en una dirección determinada (por ejemplo, 0xffff) sus instrucciones.
Normalmente habrá algún tipo de instrucción de salto en el BIOS, que configura los chips de memoria configurados, los controladores básicos del disco duro cargados, etc., etc.Luego se lee el sector de arranque del disco duro y se inicia el siguiente gestor de arranque, que carga el archivo que contiene la información básica de cómo leer, por ejemplo, una partición NTFS y cómo leer el archivo kernel. El entorno del kernel se configurará, se cargará el kernel, y luego - y luego! - se saltará el núcleo para su ejecución.
Después de todo ese trabajo duro que se ha hecho, el núcleo puede proceder a cargar nuestro software.
El sistema operativo llama a una función incluida en el tiempo de ejecución de C (CRT) y está vinculada a su ejecutable. Llamar a esto "CRT principal".
CRT main hace algunas cosas, las dos más importantes, al menos en C++, son ejecutar una variedad de clases globales de C++ y llamar a sus constructores, y llamar a su función main() y dar su retorno valor para el shell.
La fuente CRT principal de Visual C++ hace algunas cosas más, si la memoria sirve. Configura el asignador de memoria, importante si se usa Debug CRT para ayudar a encontrar fugas de memoria o malos accesos. También llama a main dentro de un controlador structured exception que atrapa el acceso a memoria defectuosa y otros bloqueos y los muestra.
Aunque estás hablando de C++ no C, ¡tu publicación es esclarecedora! –
Probablemente la mejor información para su pregunta se puede encontrar en el siguiente enlace http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html, la mejor que he encontrado hasta la fecha.
¡Eso es genial! ¡Muchas gracias! –
- 1. ¿Cómo se llama a un método desde static main()?
- 2. El método Objective-C no se llama
- 3. ¿Cómo se usa el método getView() y dónde se llama?
- 4. ¿cuándo se llama el método dealloc?
- 5. NSFilePresenter -presentedSubitemDidAppearAtURL: el método nunca se llama
- 6. ¿Cuándo se llama el método layoutSubviews?
- 7. ¿Cómo se llama este método de almacenamiento?
- 8. El método "clickedButtonAtIndex:" delegado no se llama
- 9. C# Forma de nombrar el método Main() por ti mismo?
- 10. Método de ejecución (mágico) cuando se llama el método existente
- 11. C# - ¿Cómo se llama esta técnica?
- 12. ¿Cómo se llama el = token?
- 13. MenuItem oculto inicialmente no se muestra cuando se llama a setVisible (verdadero)
- 14. C#: pasar el método nulo a sobrecargado, ¿qué método se llama?
- 15. ¿Cómo se llama el operador &: en Ruby?
- 16. ¿Cuándo se llama el método de finalización en la unidad?
- 17. EasyMock: prueba ese método en el simulacro no se llama
- 18. ¿Cómo se llama un método cada hora en Rails?
- 19. C# Modificador de acceso predeterminado del método Main()
- 20. Definición de main() en C
- 21. main() en C, C++, Java, C#
- 22. C++ no se llama en la subclase
- 23. ¿Cómo se llama el carácter '`'?
- 24. EasyMock: burló objeto se llama método real
- 25. Método virtual que no se llama
- 26. ¿Qué método de actividad se llama primero?
- 27. ¿Cuándo se llama al método ConvertBack?
- 28. ¿Cuándo se llama al método IEnumerator.Reset()?
- 29. WebView: WebViewClient.onPageStarted método no se llama
- 30. método acelerómetro delegado no se llama
¡Usted lo hace! Llamas al principal()! Sí, eso es correcto! ¡Si tu puedes! – recursive
¿Quién mira a los observadores? – Cascabel
El sujeto es una afirmación pero el cuerpo es una pregunta. –