Ch1.2 Programs Are Translated by Other Programs into Different Forms

Park Choong Ho·2021년 8월 9일
0

1.2 Programs Are Translated by Other Programs into Different Forms

hello 프로그램은 높은 레벨의 C 프로그램으로서 여정을 시작합니다. 왜냐하면 C 프로그램은 인간에 의해서 읽히고 이해될 수 있기 때문입니다. 하지만 hello.c를 시스템에서 돌리기 위해, 개별 C statement들은 다른 프로그램들에 의해 low-level machine-language 인스트럭션으로 변환되어야 합니다. 이 인스트럭션들은 executable object program형태로 패키지화 되어 있고 binary disk file로 저장되어 있습니다. 오브젝트 프로그램들은 executable object file이라 합니다.

유닉스 시스템에서, 소스파일에서 오브젝트 파일로의 변환은 compiler driver에 의해 수행됩니다.

linux> gcc -o hello hello.c

여기서, GCC 컴파일러 드라이버는 hello.c 소스 파일을 읽고 이를 hello라고 하는 executable object file로 변환합니다. 이 변환은 연속된 4단계로 이루어집니다. 이 4단계를 진행하는 프로그램들(preprocessor, compiler, assembler, linker)을 합쳐서 compliation system이라 합니다.

  • Preprocessing phase: 전처리기(cpp)는 원 C코드를 '#'으로 시작하는 지시자들에 따라서 수정합니다. 예를 들어, hello.c 프로그램에서의 #include <stdio.h> 명령어는 전처리기에게 시스템 헤더 파일의 stdio.h의 내용을 읽고 이를 프로그램 text에 삽입해달라고 요청합니다. 그 결과는 다른 형태의 C 프로그램이며 대개 .i 접미사가 붙습니다.
  • Compilation phase: 컴파일러(cc1)은 hello.i 텍스트 파일을 어셈블리를 포함한 hello.s 텍스트 파일로 변환합니다. hello.s 파일은 이런 정의를 가진 main 함수를 포함하고 있습니다.
1 main:
2	subq $8, %rsp
3	movl $.LCO, %edi
4	call puts
5	movl $0, %eax
6	addq $8, %rsp
7	ret

2-7 각 라인들은 하나의 저레벨 기계어 인스트럭션을 묘사하고 있습니다. 어셈블리어는 유용합니다. 왜냐하면 어셈블리는 다른 컴파일러와 다른 고레벨 언어들에 통용되는 언어를 제공하기 때문입니다. 예를 들어, C 컴파일러와 포트란 컴파일러는 모두 같은 어셈블리어 결과 파일을 생성합니다.

  • Assembly phase: 그 다음, 어셈블러(as)는 hello.s를 기계어 인스트럭션으로 변환시킵니다. 기계어 인스트럭션들은 relocatable object라 알려진 형태로 묶여있고 그 결과를 오브젝트 파일인 hello.o로 저장해줍니다. 이 파일은 메인 함수 인스트럭션을 인코딩한 17 바이트를 포함한 바이너리 파일입니다. 만약 우리가 hello.o 파일을 텍스트 편집기로 보려고 하면 알아볼 수 없을 것입니다.
  • Linking phase: hello 프로그램이 모든 C 컴파일러가 제공하는 C 표준 라이브러리의 일부인 printf 함수를 호출했음을 눈여겨 봐야합니다. printf함수는 미리 컴파일된 printf.o 오브젝트 파일에 있습니다. 이 부분은 hello.o 프로그램에 합쳐져야 합니다. 링커는 이 결합을 실행합니다. 그 결과가 hello 파일이고 이는 executable object file입니다. 이 executable object file은 메모리에 로드되서 시스템에 의해 실행될 준비가 된 상태입니다.
profile
백엔드 개발자 디디라고합니다.

0개의 댓글