2021. 7. 16. 18:38ㆍ컴퓨터 과학
컴파일링이란 무엇인가?
우리가 C언어로 이루어진 <file_name>.c를 작성하고 ./<compiler name> <file_name>을 입력하면
컴파일러는 전처리 - 컴파일 - 어셈블 - 링크의 과정을 거쳐 실제 사용할 수 있는 파일을 만들어낸다.
인간 친화적으로 작성된 코드를 컴퓨터가 이해할 수 있는 코드로 변환시켜주는 과정을 컴파일이라고 한다.
예시로 헬로월드 컴파일링 과정이나 보자꾸나

전처리
전처리는 컴파일 전 전처리기에 의해 실행되며, 코드 내의 #으로 시작되는 모든 것은 전처리기에 의해 변환된다.
예를 들어 #include <stdio.h>는 lib의 stdio.h에 있는 모든 코드를 #include <stdio.h>의 위치에 작성하며, #include "a.h"같은 사제 헤더는 해당 .c 파일이 위치한 디렉토리에서 상대경로를 통해 a.h라는 헤더의 모든 코드를 복사해넣으며, #define 등 #으로 시작하는 모든 코드들은 전처리기에서 코드로 변환된다.

이렇게 전처리가 끝나면 .c 파일이 .i 파일이 되어 나오는데,

거의 540줄 정도 되는 묵직한 헤더가 올라타있는 모습이다.
컴파일
전처리기가 전처리가 끝낸 코드를 생성하면, 컴파일러는 해당 코드를 약간 더 저수준 언어인 어셈블리 코드로 변환한다.
명령어 집합이라고 불리는 어셈블리 코드는 해당 cpu에서 명령을 직접적으로 실행할 수 있는 코드로 c에 비해 사용할 수 있는 명령이 훨씬 적으나 이를 적절히 조합하면 c의 동작을 구현할 수 있다.


문자열 섹션을 만들고 출력하는 과정이 어셈블리로 나열되어있다.
조금 더 기계어에 가깝다 보니 C에 비해 코드가 20줄 이상 늘어났다.
어셈블
컴파일러에서 넘어온 어셈블리 코드들을 0과 1로 이루어진 바이너리 코드로 변환해 놓지만 각각의 주소는 없는 상태라 실행은 불가능하다.


:를 입력해 커맨드로 들어가서 %!xxd를 입력하면 vi hexeditor로 대충 그래도 뭔가를 볼 수 있는 화면으로 바꿀 수 있다.

여기서 뭔가를 수정하고 다시 :%!xxd -r을 입력하면 아까 화면으로 돌아가게된다.
얘네는 그냥 코드 덩어리고 주소가 정해지지 않은 상태이다.
링크
코드를 짜다보면 이렇게 단순하게 .c 하나만 만들지 않고, 여러개의 .c 파일과 라이브러리 등등이 필요하게 되는데, 이러한 여러개의 오브젝트들이 해당 과정에서 엮이고 주소를 부여받아 실제로 쓸 수 있는 코드가 된다.




아스키 코드와 비교해보자.
68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 0a
'h' 'e' 'l' 'l'. 'o' ',' ' ' 'w' 'o' 'r' 'l' 'd' '\n'
문자열의 주소의 위치부터 1바이트씩 아스키 코드가 저장되어있다.

실행이 완료된 모습.
사실 최적화나 그런거 다 빼고 최소한의 옵션으로 코드가 실행되기까지의 과정을 적어보았다.
도움이 되었으면 함 ㅎ
참고. gcc --save-temps *.c 하면 중간 중간의 임시 파일이 생성된다.
그럼 안녕
'컴퓨터 과학' 카테고리의 다른 글
Docker) 초보자를 위한 도커 설명회 (0) | 2023.01.30 |
---|---|
git) 프라이빗 레포 다른 컴퓨터에서 사용하기 (0) | 2021.10.16 |
CS 50 - 메모리와 데이터의 저장 (0) | 2021.07.18 |
CS 50 - 16진법과 포인터, Call by reference (0) | 2021.07.18 |
CS 50 - 컴퓨터 과학과 컴퓨팅 사고 (0) | 2021.07.16 |