프로그램의 인코딩

이후띵·2021년 12월 9일
0

컴퓨터시스템

목록 보기
3/8

C 프로그램을 두개의 파일 p1.c, p2.c에 작성한다고하자. 이 코드를 유닉스 커맨드 라인으로 다음과 같이 컴파일 한다.

linux> gcc -0g -o p p1.c p2.c

명령어는 GCC C 컴파일러를 지정한다. 이것이 리눅스에서 기본 컴파일러이기 때문에 이것은 간단히 cc로 호출할 수도 있었다. 커맨드 라인 옵션으로 -0g을 주면 컴파일러는 본래 C 코드의 전체 구조를 따르는 기계어 코드를 생성하는 최적화 수준을 적용한다. 일반적으로 최적화 수준을 올리게 되면 최종 프로그램은 더 빨리 동작하게 되지만, 컴파일 시간이 증가하고, 디버깅 도구를 실행하기가 어려워질 위험이 있다. 나중에 알게 되겠지만 높은 수준의 최적화를 적용하면 만들어진 코드가 너무 많이 변경되어서 본래의 코드와 생성된 기계어 코드 간의 관계를 이해하기가 어렵다. 그래서 공부를 위해 -0g 최적화를 적용하고 최적화 단계를 올리면 무슨일이 생기는지 살펴보고자 한다. 실제로는 더 높은 단계의 최적화 ( 예. 옵션 -01이나 -02로 설정)가 프로그램 성능적인 면에서 더 좋은 선택이다.

      gcc 명령은 소스 코드를 실행 코드로 변환하기 위해 일련의 프로그램들을 호출한다. 먼저, C 전처리기가 #include 로 명시된 파일을 코드에 삽입해 주고, define으로 선언된 매크로를 확장해 준다. 두 번째로, 컴파일러는 두개의 소스파일의 어셈블리 버전인 p1.s와 p2.s를 생성한다. 다음으로 어셈블러는 어셈블리 코드를 바이너리 목적코드인 p1.o와 p2.o로 변환한다. 목적코드는 기계어 코드의 한 유형이다. 모든 인스트럭션의 바이너리 표현을 포함하고 있지만 전역 값들의 주소는 아직 채워지지 않았다. 마지막으로 링커는 두개의 목적코드 파일을 라이브러리 함수들을 구현한 코드와 함께 합쳐서 최종 실행파일인 p를 생성한다.(명령줄 디렉티브 -op로 명시하여). 실행코드는 우리가 다루게 될 두 번째 형태의 기계어 코드이다. 이것이 프로세서가 실행할 정확한 코드의 형태이다. 이들 다른 형태의 기계어 코드들과 링크 과정과의 관계는 나중에 다룬다.

profile
이후띵's 개발일지

0개의 댓글