В программе C / C++ как система (windows, linux, mac OS X) вызывает функцию main ()

Я ищу более техническое объяснение, то ОС вызывает функцию.
Может ли кто-нибудь помочь мне или указать мне веб-сайт или книгу?

7 ответов

  1. main() является частью библиотеки C и не является системной функцией. Я не знаю для OS X или Linux ,но Windows обычно запускает программуWinMainCRTStartup(). Этот символ init ваш процесс, извлечь аргументы командной строки и среды (argc, argv, end) и вызовыmain(). Он также отвечает за вызов любого кода, который должен выполняться послеmain(), как atexit().

    Заглянув в файл Visual Studio, вы сможете найти реализацию по умолчаниюWinMainCRTStartup, чтобы увидеть, что она делает.

    Вы также можете определить собственную функцию для вызова при запуске, это делается путем изменения «точки входа» в параметрах компоновщика. Это часто функция, которая не принимает никаких аргументов и возвращает void.

  2. Этот.exe-файл (или эквивалент на других платформах) содержит адрес точки входа. В первом приближении ОС загружает соответствующие секции .EXE-файл в оперативную память, а затем переходит к точке входа.

    Как говорили другие, эта точка входа не будет «главной», а будет частью библиотеки времени выполнения — она будет выполнять такие действия, как инициализация статических объектов, настройка параметров argc/argv, настройка stdin/stdout/stderr и т.д. Когда все это будет сделано, он вызовет вашу функцию main (). При выходе из main среда выполнения проходит через аналитический процесс передачи кода возврата в среду, вызова статических деструкторов,вызова процедур _atexit и т.д.

    Если у вас есть MS tools (возможно, не freebie), то у вас есть весь источник среды выполнения, и простой способ взглянуть на него-поставить точку останова на закрывающей скобке вашего метода main() и сделать один шаг назад в среду выполнения.

  3. Expert C++ / CLI (проверьте страницу 279) имеет очень конкретные детали различных сценариев начальной загрузки для собственных, смешанных и чистых сборок CLR.

  4. Это зависит от операционной системы.
    В OS X в заголовке mach есть рамка, которая содержит начальный адрес для регистра EIP (указатель инструкции).

    После загрузки двоичного файла ОС запускает выполнение с этого адреса:

    cristi: test diciu$ otool-l ./ a.out / grep-A 10 LC_UNIXTHREAD
     cmd LC_UNIXTHREAD
     cmdsize 80
     flavor i386_THREAD_STATE
     count i386_THREAD_STATE_COUNT
    [..]
     ss 0x00000000 eflags 0x00000000 eip 0x00001f8c cs 0x00000000
    [..]
    

    Адрес-адрес функции «start» из двоичного файла:

    cristi: тест diciu$ nm ./ a.вне
    0000200c D _NXArgc
    00002008 D _NXArgv
    00002000 D _ _ _ progname
    00001fe0 t _ _ dyld_func_lookup
    00001000 a __MH_execute_заголовок
    [..]
    00001f8c t начало
    

    В Mac OS X функция» start «вызывается первой, еще до функции» main»:

    (gdb) B начало
    Точка останова 1 на 0x1f90
    (gdb) B main
    Точка останова 2 на 0x1ff4
    (gdb) r
    Запуск программы: / пользователи / diciu / Программирование / тест / a.вне 
    Чтение символов для общих библиотек ++. сделанный
    
    Точка останова 1, 0x00001f90 в пуске ()
    
  5. Насколько windows идет, функции точки входа:

    • Приставка: void __cdecl mainCRTStartup( void ) {}
    • ГРАФИЧЕСКИЙ ИНТЕРФЕЙС ПОЛЬЗОВАТЕЛЯ: void __stdcall WinMainCRTStartup( void ) {}
    • файл DLL: BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL,DWORD fdwReason,void* lpReserved) {}

    Единственная причина использовать их над обычным main / WinMain/DllMain, если вы хотите использовать свою собственную библиотеку времени выполнения (если вы хотите меньший размер файла или пользовательские функции)

    Сведения о пользовательских реализациях времени выполнения и других способах получения файлов PE меньшего размера см. В разделе:

  6. Если вас интересует книга, связанная с Windows и Win32 API попробуйте

    «Программирование приложений для Microsoft Windows» Джеффри Рихтера.