리얼 개발

[CS] 프로그램이 실행되기 까지 과정 본문

Computer Science/기타

[CS] 프로그램이 실행되기 까지 과정

econo-my 2025. 3. 5. 14:35

0. 소스 코드 작성 ( Source Code )

C++로 소스 코드를 작성했다고 가정

ex) main.c

 

1. 전처리 ( Preprocessing )

컴파일러가 코드를 해석하기 전에 전처리기 ( preprocessor ) 가 동작하여 #include, #define 같은 지시문을 처리한다.

#include <iostream>

해당 헤더파일이 실제 코드로 변환됨.

그 후 .i 파일이 생성됨.

ex) main.c → main.i

 

2. 컴파일 ( Compilation )

전처리된 .i 파일이 컴파일러를 통해 중간 언어인 어셈블리어로 변환됨.

ex) main.i → main.s

 

3. 어셈블 ( Assembly )

컴파일러가 생성한 중간 언(어셈블리 코드)를 어셈블러 ( Assembler ) 가 변환하여 바이너리 형태의 오브젝트 파일을 생성한다.

ex) main.s → main.obj

 

 

여기까지 컴파일 과정


여기서부턴 빌드 과정

빌드 과정을 끝마치면 실행 파일이 생성됨.

 

 

4. 링킹 ( Linking )

ex) main.obj → .exe

각각의 오브젝트 파일들은 링커 ( Linker ) 에 의해 하나의 실행 파일( .exe/ .out ) 로 결합됨.

링커는 실행 파일을 만들면서 여러가지 일을 수행하게 됨.

  1. 심볼 ( Symbol ) 해결
    • 컴파일러가 .obj 파일을 만들 때, 함수나 변수의 주소를 정확히 모름
    • 링커는 모든 오브젝트 파일을 검색해서 필요한 함수나 변수를 찾아 연결함
    • ex) .h 에 함수 선언 후 .cpp 에서 함수 정의
  2. 주소 할당 ( Address Allocation )
    • 각 오브젝트 파일이 갖고 있는 코드와 데이터들을 메모리에 적절한 위치에 배치함
    • 모든 함수와 변수에 대한 실제 메모리 주소가 확정됨
  3. 라이브러리 결합 ( Library Linking )
    • 프로그램이 표준 라이브러리와 같은 외부 라이브러리를 사용하면 이를 추가해야함
    • 정적 ( .lib ) 과 동적 ( .dll ) 라이브러리가 있음
    • 정적 라이브러리 ( .lib / .a )
      • 링커가 실행 파일 안에 .lib 내용을 포함 → 배포 시 별도 라이브러리 필요 없음
      • ex) math.lib
    • 동적 라이브러리 ( .dll / .so )
      • 링커가 실행 파일에서 DLL 파일을 찾아서 사용할 수 있도록 참조만 추가
      • 실행할 때만 .dll 을 로드 → 실행 파일 크기가 작아짐
      • ex) user32.dll, kernel32.dll

 

5. 실행 ( Execute )

위의 과정이 끝나면 윈도우의 경우 .exe 파일이 생김. ( 리눅스는 .out )

그 후 프로그램의 실행 과정은 다음과 같음.

  • 사용자 요청
    • 사용자가 실행 파일(.exe)을 더블 클릭하거나 명령 프롬프트에서 실행 명령을 입력함.
  • 파일 시스템 접근
    • 운영 체제는 파일 시스템에서 해당 .exe 파일을 찾고 접근 권한을 확인함.
    • 운영체제 역할
  • 보안 검사
    • 사용자 계정 컨트롤(UAC): 프로그램이 관리자 권한을 필요로 할 경우, UAC 창이 나타나 사용자에게 권한 승인을 요청함.
    • 흔히 보이는 그 관리자 권한 요청
  • 안티바이러스 검사
    • 일부 보안 소프트웨어는 실행 전에 파일을 스캔하여 악성 코드 여부를 확인함.
  • 프로세스 생성 요청
    • 운영 체제의 커널은 새로운 프로세스를 생성하기 위해 내부적으로 시스템 호출을 수행함.
    • System Call
  • 실행 파일 로딩
    • PE(Portable Executable) 형식 분석: .exe 파일의 헤더 정보를 읽어 실행에 필요한 정보(코드, 데이터, 리소스 등)를 파악함.
    • 메모리 할당: 프로세스에 필요한 가상 메모리 공간을 할당함.
    • 코드 및 데이터 로드: 실행에 필요한 코드 섹션과 데이터 섹션을 메모리에 로드함.
  • 의존성 해결 및 DLL 로딩
    • 프로그램이 사용하는 동적 링크 라이브러리(DLL)를 찾고 로드함.
    • 필요한 경우, 추가적인 의존성 파일들도 로드함.
  • 프로세스 환경 설정
    • 환경 변수, 작업 디렉토리, 표준 입출력 핸들 등이 설정함.
    • 스레드 스택과 힙 영역이 초기화함.
  • 프로그램 초기화
    • 런타임 라이브러리 초기화: C/C++의 경우, 런타임 라이브러리가 초기화되어 전역 변수와 static 변수가 설정됨.
    • 프로그램 진입점 호출: 일반적으로 main() 또는 WinMain() 함수가 호출됨.
  • 코드 실행
    • 프로그램의 메인 로직이 실행되며, 사용자의 입력이나 시스템 이벤트를 처리함.
  • 프로세스 종료
    • 프로그램이 종료되면, exit() 함수나 반환값을 통해 운영 체제에 종료 상태를 전달함.
    • 운영 체제는 할당된 메모리를 해제하고, 열린 파일이나 리소스를 정리함.
  • 후처리 작업
    • 종료 코드가 부모 프로세스나 호출자에게 반환됨.
    • 로그 작성이나 이벤트 트리거 등의 후처리 작업이 수행될 수 있음.
  • 추가 사항
    • 멀티스레딩: 프로그램이 여러 개의 스레드를 생성하는 경우, 각 스레드는 독립적으로 스케줄링되고 관리됨.
    • 예외 처리: 실행 중 예외 상황이 발생하면, 예외 처리 루틴이 실행되어 오류를 처리하거나 프로그램을 안전하게 종료함.
    • 가상 메모리 및 페이지 매핑: 운영 체제는 가상 메모리 시스템을 통해 프로세스의 메모리 접근을 관리함.

'Computer Science > 기타' 카테고리의 다른 글

[CS] 함수 호출 규약 (Function Calling Convention)  (0) 2025.04.07