C/C++ 프로그램에서 시스템(windows, linux, mac OS X)은 어떻게 main() 함수를 호출합니까?

StackOverflow https://stackoverflow.com/questions/12332

  •  08-06-2019
  •  | 
  •  

문제

OS가 함수를 호출하는 것보다 더 기술적인 설명을 찾고 있습니다.누군가 나를 도와주거나 웹사이트나 책을 알려줄 수 있나요?

도움이 되었습니까?

해결책

.exe 파일(또는 다른 플랫폼의 경우 이에 상응하는 파일)에는 '진입점' 주소가 포함되어 있습니다.첫 번째 근사치로 OS는 .EXE 파일의 관련 섹션을 RAM에 로드한 다음 진입점으로 점프합니다.

다른 사람들이 말했듯이 이 진입점은 'main'이 아니라 대신 런타임 라이브러리의 일부가 될 것입니다. 이는 정적 객체 초기화, argc/argv 매개변수 설정, stdin/stdout/stderr 설정과 같은 작업을 수행합니다. , 등.모든 작업이 완료되면 main() 함수가 호출됩니다.기본 종료 시 런타임은 반환 코드를 환경으로 다시 전달하고, 정적 소멸자를 호출하고, _atexit 루틴을 호출하는 등의 유사한 프로세스를 거칩니다.

MS 도구(공짜 도구는 아님)가 있는 경우 모든 런타임 소스가 있는 것이며 이를 확인하는 쉬운 방법은 main() 메서드의 닫는 중괄호에 중단점을 놓고 한 단계 백업하는 것입니다. 런타임에.

다른 팁

main() C 라이브러리의 일부이며 시스템 기능이 아닙니다.OS X나 Linux에 대해서는 잘 모르지만 Windows는 일반적으로 다음과 같이 프로그램을 시작합니다. WinMainCRTStartup().이 기호는 프로세스를 초기화하고 명령줄 인수와 환경을 추출합니다(argc, argv, end) 그리고 전화 main().또한 이후에 실행되어야 하는 모든 코드를 호출하는 일도 담당합니다. main(), 좋다 atexit().

Visual Studio 파일을 살펴보면 다음의 기본 구현을 찾을 수 있습니다. WinMainCRTStartup 그것이 무엇을 하는지 보기 위해.

시작 시 호출할 함수를 직접 정의할 수도 있습니다. 이는 링커 옵션에서 "진입점"을 변경하여 수행됩니다.이는 인수를 사용하지 않고 void를 반환하는 함수인 경우가 많습니다.

창에 관한 한 진입점 기능은 다음과 같습니다.

  • 콘솔: void __cdecl mainCRTStartup( void ) {}
  • GUI: void __stdcall WinMainCRTStartup( void ) {}
  • DLL: BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL,DWORD fdwReason,void* lpReserved) {}

일반 main/WinMain/DllMain 대신 이를 사용하는 유일한 이유는 자체 런타임 라이브러리를 사용하려는 경우입니다(더 작은 파일 크기 또는 사용자 정의 기능을 원하는 경우).

더 작은 PE 파일을 얻기 위한 사용자 지정 런타임 구현 및 기타 요령은 다음을 참조하세요.

전문가 C++/CLI (279페이지 확인)에는 네이티브, 혼합 및 순수 CLR 어셈블리에 대한 다양한 부트스트랩 시나리오에 대한 매우 구체적인 세부 정보가 있습니다.

OS에 따라 다릅니다.OS X에는 EIP(명령 포인터) 레지스터의 시작 주소를 포함하는 mach 헤더의 프레임이 있습니다.

바이너리가 로드되면 OS는 다음 주소에서 실행을 시작합니다.

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
[..]

주소는 바이너리의 "시작" 함수 주소입니다.

cristi:test diciu$ nm ./a.out
0000200c D _NXArgc
00002008 D _NXArgv
00002000 D ___progname
00001fe0 t __dyld_func_lookup
00001000 A __mh_execute_header
[..]
00001f8c T start

Mac OS X에서는 "main" 함수 이전에도 "start" 함수가 먼저 호출됩니다.

(gdb) b start
Breakpoint 1 at 0x1f90
(gdb) b main
Breakpoint 2 at 0x1ff4
(gdb) r
Starting program: /Users/diciu/Programming/test/a.out 
Reading symbols for shared libraries ++. done

Breakpoint 1, 0x00001f90 in start ()

Windows 및 Win32 API 관련 책에 관심이 있다면 시도해 보세요.

Jeffrey Richter의 "Microsoft Windows용 프로그래밍 응용 프로그램".

다음 링크를 살펴볼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top