programing

C 프로그램에는 main()이 필요합니까?

closeapi 2023. 6. 15. 21:51
반응형

C 프로그램에는 main()이 필요합니까?

제목이 모든 것을 말해줍니다.는 사입니다.main()C 프로그램에 절대적으로 필수적인 기능?

리눅스 커널 코드를 보고 있는데 메인() 기능이 보이지 않아서 문의드립니다.

C에는 ISO C 표준이라고 있습니다.main기능은 기본 OS가 있는 호스트 환경에만 필요합니다.

임베디드 시스템(또는 운영 체제 자체)과 같은 독립형 환경의 경우 구현이 정의됩니다. C99에서 합니다.5.1.2:

두 가지 실행 환경, 즉 독립형 및 호스트형이 정의됩니다.두 경우 모두 실행 환경에서 지정된 C 함수를 호출할 때 프로그램 시작이 발생합니다.

독립적인 환경(운영 체제의 이점 없이 C 프로그램을 실행할 수 있는 환경)에서 프로그램 시작 시 호출되는 함수의 이름과 유형은 구현 정의됩니다.

리눅스 자체가 어떻게 시작되는지에 관해서는 리눅스 커널의 시작점은 start_kernel이지만, 전체 부팅 프로세스에 대한 보다 완전한 그림을 보려면 여기서 시작해야 합니다.

아뇨, 하지만...

는 C99를 합니다.main()호스트 환경에서 "프로그램 시작 시" 를 호출하지만 C 런타임 지원을 사용할 필요는 없습니다.운영 체제가 이미지 파일을 실행하고 링커가 제공한 주소에서 프로그램을 시작합니다.

C99가 아닌 운영 체제의 요구 사항에 맞게 프로그램을 작성할 의향이 있다면 main() 없이도 할 수 있습니다.그러나 시스템이 더 현대적이고 복잡할수록 표준 런타임 시작이 사용된다고 가정하는 C 라이브러리에 더 많은 문제가 발생할 것입니다.

다음은 Linux의 예입니다.

$ cat > nomain.S
.text
_start:
    call    iamnotmain
    movl    $0xfc, %eax
    xorl    %ebx, %ebx
    int     $0x80
.globl _start
$ cat > demo.c

void iamnotmain(void) {
    static char s[] = "hello, world\n";
    write(1, s, sizeof s);
}
$ as -o nomain.o nomain.S
$ cc -c demo.c
$ ld -static nomain.o demo.o -lc
$ ./a.out
hello, world

하지만 이제는 거의 틀림없이 "C99 프로그램"이 아니라 객체 모듈이 C로 작성된 "리눅스 프로그램"일 뿐입니다.

main()함수는 libc에 포함된 개체 파일에 의해 호출됩니다.커널은 libc에 대해 링크되지 않기 때문에 어셈블러로 작성된 자체 진입점이 있습니다.

팍스디아블로의 대답은 당신이 메인을 마주치지 않을 경우 중 두 가지를 포함합니다.몇 가지를 더 추가하겠습니다.

  • 또는 등에는 " " " " (으: 브우을예프램등편그로텍기집또트시는스에스인템다위플그른러많한은는저라을예(▁many")가 .main().
  • C로 작성된 Windows 프로그램에 없음main()(그들은 가지고 있습니다.WinMain()대신.)

운영 체제 로더는 단일 진입점을 호출해야 합니다. GNU 컴파일러에서 진입점은 crt0.o 연결된 객체 파일에 정의되어 있으며, 이에 대한 소스는 다양한 런타임 시작 작업(스택 설정, 정적 초기화 등)을 수행한 후 main()을 호출하는 어셈블리어 파일 crt0.s입니다.따라서 기본 crt0.o를 연결하는 실행 파일을 빌드할 때 main()이 있어야 합니다. 그렇지 않으면 incrt0.o main()이 확인되지 않은 기호이므로 링커 오류가 발생합니다.

crt0.s를 수정하여 다른 진입점을 호출할 수 있습니다(비뚤어지고 불필요한 경우).기본 버전을 수정하는 대신 프로젝트에 특정한 개체 파일을 만들어야 합니다. 그렇지 않으면 해당 시스템의 모든 빌드가 손상됩니다.

OS 자체에는 자체 C 런타임 시작(부트로더에서 호출됨)이 있으므로 원하는 진입점을 호출할 수 있습니다.리눅스 소스를 본 적은 없지만, C 코드 진입점이 무엇이든 호출할 수 있는 자체 crt0.s가 있다고 상상해 보십시오.

main은 glibc에 의해 호출되며, 이는 커널(링 0)이 아닌 애플리케이션(링 3)의 일부입니다.
드라이버에 다른 진입점이 있습니다. 예를 들어 WDM의 Windows 드라이버 기반은 DRIVENTRY에서 시작됩니다.

기계 언어에서 사물들은 순차적으로 실행되고, 먼저 오는 것이 먼저 실행됩니다.기본값은 컴파일러가 C 표준에 맞게 메인 메서드를 호출하는 것입니다.

프로그램은 컴파일된 함수의 모음인 라이브러리처럼 작동합니다.라이브러리와 표준 실행 파일의 주요 차이점은 컴파일러가 프로그램의 함수 중 하나를 호출하는 어셈블리 코드를 생성한다는 것입니다.

그러나 임의의 C 프로그램 함수를 호출하는 어셈블리 코드를 작성할 수 있으며(실제로 라이브러리 함수 호출이 작동하는 방식과 동일), 이것은 다른 실행 파일과 동일하게 작동합니다.하지만 문제는 당신이 그것을 일반적인 표준 C에서 할 수 없다는 것입니다. 당신은 어셈블리나 심지어 다른 컴파일러 특정 트릭에 의존해야 합니다.

이는 일반적이고 피상적인 설명을 의도한 것으로, 관련성이 없어 보여 일부러 피한 기술적 차이가 있습니다.

언급URL : https://stackoverflow.com/questions/4113731/is-a-main-required-for-a-c-program

반응형