En C, ¿cómo se llama inicialmente al método main()?

8 minutos de lectura

En C ¿como se llama inicialmente al metodo main
usuario418627

¿Cómo se inicia un programa en C?

  • ¡Tú haces! ¡Llamas al main()! ¡Sí, eso es correcto! ¡Si tu puedes!

    – recursivo

    12 de agosto de 2010 a las 16:41

  • ¿Quién vigila a los vigilantes?

    – Cascabel

    12 de agosto de 2010 a las 16:41

  • El sujeto es un enunciado pero el cuerpo es una pregunta.

    – Brian R. Bondy

    12 de agosto de 2010 a las 16:43

  • ¿Por qué, Justin, por qué? ¡Era poesía!

    – jball

    12 de agosto de 2010 a las 17:21

  • Guau, la forma en que evoluciona esta pregunta me recuerda a “¿Cómo muevo la tortuga en LOGO?”

    – Brian

    12 de agosto de 2010 a las 17:53

En C ¿como se llama inicialmente al metodo main
zan lince

El sistema operativo llama al main() función. Finalmente.

los Formato ejecutable y enlazable (ELF) que muchos sistemas operativos Unix utilizan define una dirección de punto de entrada y una dirección INIT. Ahí es donde el programa comienza a ejecutarse después de que el sistema operativo finaliza su exec() llamada. En un sistema Linux esto es _init en el .init sección. Después de eso, salta a la dirección del punto de entrada que es _start en el .text sección.

El compilador de C vincula una biblioteca estándar a cada aplicación que proporciona estos puntos de entrada y de inicialización definidos por el sistema operativo. Esa biblioteca entonces llama main().

Aquí está mi código fuente C para el ejemplo:

#include <stdio.h>

int main() {
  puts("Hello world!");
  return 0;
}

Desde objdump -d:

Disassembly of section .init:

0000000000001000 <_init>:
    1000:   f3 0f 1e fa             endbr64 
    1004:   48 83 ec 08             sub    $0x8,%rsp
    1008:   48 8b 05 d9 2f 00 00    mov    0x2fd9(%rip),%rax        # 3fe8 <__gmon_start__>
    100f:   48 85 c0                test   %rax,%rax
    1012:   74 02                   je     1016 <_init+0x16>
    1014:   ff d0                   callq  *%rax
    1016:   48 83 c4 08             add    $0x8,%rsp
    101a:   c3                      retq   

Disassembly of section .text:

0000000000001060 <_start>:
    1060:   f3 0f 1e fa             endbr64 
    1064:   31 ed                   xor    %ebp,%ebp
    1066:   49 89 d1                mov    %rdx,%r9
    1069:   5e                      pop    %rsi
    106a:   48 89 e2                mov    %rsp,%rdx
    106d:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    1071:   50                      push   %rax
    1072:   54                      push   %rsp
    1073:   4c 8d 05 66 01 00 00    lea    0x166(%rip),%r8        # 11e0 <__libc_csu_fini>
    107a:   48 8d 0d ef 00 00 00    lea    0xef(%rip),%rcx        # 1170 <__libc_csu_init>
    1081:   48 8d 3d c1 00 00 00    lea    0xc1(%rip),%rdi        # 1149 <main>
    1088:   ff 15 52 2f 00 00       callq  *0x2f52(%rip)          # 3fe0 <__libc_start_main@GLIBC_2.2.5>
    108e:   f4                      hlt    
    108f:   90                      nop

0000000000001140 <frame_dummy>:
    1140:   f3 0f 1e fa             endbr64 
    1144:   e9 77 ff ff ff          jmpq   10c0 <register_tm_clones>

Desde readelf -h puede ver la dirección del punto de entrada que coincide _start:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1060
  Start of program headers:          64 (bytes into file)
  Start of section headers:          17416 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         36
  Section header string table index: 35

Desde readelf -d:

Dynamic section at offset 0x2dc8 contains 27 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000c (INIT)               0x1000
 0x000000000000000d (FINI)               0x11e8
 0x0000000000000019 (INIT_ARRAY)         0x3db8
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x3dc0
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x3a0
 0x0000000000000005 (STRTAB)             0x470
 0x0000000000000006 (SYMTAB)             0x3c8
 0x000000000000000a (STRSZ)              130 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x3fb8
 0x0000000000000002 (PLTRELSZ)           24 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x5e0
 0x0000000000000007 (RELA)               0x520
 0x0000000000000008 (RELASZ)             192 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000000000001e (FLAGS)              BIND_NOW
 0x000000006ffffffb (FLAGS_1)            Flags: NOW PIE
 0x000000006ffffffe (VERNEED)            0x500
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x4f2
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000000 (NULL)               0x0

Puede ver que INIT es igual a la dirección de _init.

Hay toda una serie de punteros de función en INIT_ARRAY también. Ver objdump -s -j .init_array c-test:

c-test:     file format elf64-x86-64

Contents of section .init_array:
 3db8 40110000 00000000                    @.......        

Puede ver que la dirección 0x3db8 es la misma que INIT_ARRAY en el encabezado ELF.

La dirección 0x1140 (recuerde el diseño de bytes little-endian de 40110000) es la función frame_dummy se puede ver en el desmontaje. Que luego llama register_tm_clones Y quién sabe qué más.

El código para la inicialización se encuentra en un conjunto de archivos llamados crtbegin.o y crtend.o (y variantes de esos nombres). los __libc_start_main La función se define en libc.so.6. Estas bibliotecas son parte de GCC. Ese código hace varias cosas necesarias para un programa C, como configurar 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 a continuación con menos votos): http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html

Creo que la respuesta de otra persona ya describió lo que hace Windows.

  • no llama _init o cualquier otro. llama a la dirección del punto de entrada. puede estar en cualquier lugar.

    – Andrei

    12 de agosto de 2010 a las 16:44

  • ¿SE NECESITA libstdc++.so.6? ¡Esto no es de un programa en C!

    – Jens

    3 de diciembre de 2012 a las 15:54

  • @Jens: No hace ninguna diferencia en este caso.

    – Zan Lince

    3 de diciembre de 2012 a las 17:51

  • @ZanLynx ¿Cómo puedes saberlo? ¿Cómo puedo decir? ¿Por qué no simplemente mirar un programa C en su lugar? C y C++ son lenguajes muy diferentes, y el inicio del programa es una de las áreas donde esto es visible (por ejemplo, llamar a los constructores).

    – Jens

    4 de diciembre de 2012 a las 9:19

  • @Jens: ¿Cómo puede usted decir, ya que no confías en mí? Use el desensamblador objdump -d para mirar el código de la máquina y use readelf -d para ver las cosas de ELF. O tome un editor hexadecimal y una copia de la especificación ELF.

    – Zan Lince

    5 de diciembre de 2012 a las 7:24

1646749395 184 En C ¿como se llama inicialmente al metodo main
Andrei

Eventualmente es sistema operativo. Por lo general, hay algún medio entre el punto de entrada real y la función principal, esto se inserta mediante compilador enlazador

Algunos detalles (relacionados con Windows): hay un encabezado en el archivo PE llamado IMAGE_OPTIONAL_HEADER que tiene el campo AddressOfEntryPointque a su vez es la dirección del primer byte de código del archivo que se ejecutará.

  • No lo inserta el compilador, lo inserta el enlazador, generalmente al vincularlo a algo como crt.a(crt.o) o crt.lib(crt.obj)que generalmente es parte de algo como libc.a o c.lib.

    – Christian Hujer

    11 de agosto de 2015 a las 16:11

  • @ChristianHujer tienes razón, por compilador quise decir bien la cadena de herramientas.

    – Andrei

    11 de agosto de 2015 a las 16:15

  • estas seguro de enlazadorsupongo que cargador entonces?

    – roottraveller

    11 de septiembre de 2017 a las 11:23


  • Enlaces @roottraveller Linker. Es posible que el ejecutable nunca se cargue.

    – Andrei

    11 de septiembre de 2017 a las 14:23

http://codificación.derkeiler.com/Archive/C_CPP/comp.lang.c/2008-04/msg04617.html

  • No sé por qué esto fue rechazado, el enlace tiene buena información.

    – zwol

    12 de agosto de 2010 a las 18:04

  • @Zack En general, publicar un enlace sin algún tipo de resumen aquí está mal visto

    – Michael Mrozek

    13 de agosto de 2010 a las 15:10

El sistema operativo llama a main. Habrá una dirección en el ejecutable reubicable que apunta a la ubicación de main (consulte la ABI de Unix para obtener más información).

Peroquien llama al sistema operativo?

La unidad central de procesamiento, en la señal “RESET” (que también se activa al encender), comenzará a buscar instrucciones en alguna ROM en una dirección determinada (por ejemplo, 0xffff).

Por lo general, habrá algún tipo de instrucción de salto hacia el BIOS, que configura los chips de memoria, carga los controladores básicos del disco duro, etc., etc. Luego se lee el Sector de arranque del disco duro y el próximo Se inicia el cargador de arranque, que carga el archivo que contiene la información básica sobre cómo leer, por ejemplo, una partición NTFS y cómo leer el archivo del kernel en sí. Se configurará el entorno del kernel, se cargará el kernel y luego… ¡y luego! – se saltará al núcleo para su ejecución.

Después de que se haya realizado todo ese trabajo duro, el kernel 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 vinculada a su ejecutable. Llame a esto “CRT principal”.

CRT main hace algunas cosas, las dos más importantes, al menos en C++, son ejecutar una matriz de clases globales de C++ y llamar a sus constructores, y llamar a su función main() y dar su valor de retorno al shell .

El CRT principal de Visual C++ hace algunas cosas más, si la memoria no me falla. 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 excepción estructurada controlador que detecta el acceso incorrecto a la memoria y otros bloqueos y los muestra.

  • A pesar de que está hablando de C ++, no de C, ¡su publicación es esclarecedora!

    – Gab是好人

    9 dic 2016 a las 18:25

1646749396 793 En C ¿como se llama inicialmente al metodo main
Brian

Tenga en cuenta que además de las respuestas ya publicadas, también es posible que llame main tú mismo. En general, esta es una mala idea reservada para el código ofuscado.

  • A pesar de que está hablando de C ++, no de C, ¡su publicación es esclarecedora!

    – Gab是好人

    9 dic 2016 a las 18:25

En C ¿como se llama inicialmente al metodo main
Nandan Bharadwaj

Probablemente la mejor información para su pregunta se puede encontrar en el enlace mencionado a continuación
http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.htmlel mejor que he encontrado hasta la fecha.

  • ¡Eso es genial! ¡Muchas gracias!

    – Gab是好人

    9 dic 2016 a las 18:26

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad