지난 1년간 실무를 경험하면서 부족했던 근본지식을 채우고 내 머릿속 컴퓨터 지식들을 도식화하기 위해
컴퓨터 구조와 운영체제를 공부하고있다.
아마 웹/앱개발을 한 사람이라면, 이미 C언어보다는 다른 프로그래밍 언어를 주로 다루고 있을 가능성이 높겠지만.
C언어는 다른 프로그래밍 언어의 기반이 되는 언어이기도하다.
C언어 내부적 컴파일 과정을 이해하면, C언어의 작동 방식과 이를 이용한 프로그래밍 기법을 이해할 수 있게 된다.
그렇다고 갑자기 C언어를 메인언어로 갈예정은 전혀 아니다. 컴퓨터 구조를 이해하기 위해 공부하는 것이다.
개발 시 컴파일 에러 메시지를 이해하고 수정하는 데 깊은 이해 덕분에 도움이 될것같다.
C언어 내부적 컴파일 과정에 대해 알아보도록 하자.
C 언어 소스 코드를 컴파일하여 실행 파일을 생성하기 위해서는 4가지 과정을 거쳐야한다.
괴정은 다음 내용과 같다.

test.c 파일을
컴파일하여 실행 가능한 프로그램을 생성하는 과정 C 소스 코드 파일이다.
#include <stdio.h>
int main() {
printf("Hello, world!\\n");
return 0;
}
전처리기(preprocessor) 단계:
#include <stdio.h>
#define MAX 100
int main() {
printf("Hello, world!\\n");
return 0;
}
test.c 파일에는 전처리기 지시자(preprocessor directive)가 포함될 수 있다.
이 지시자들은 # 문자로 시작한다. 전처리기는 이러한 지시자들을 처리하고,
test.c 파일에서 이에 해당하는 내용을 가져와 test.i 파일에 저장한다.
컴파일러(compiler) 단계:
test.i 파일에는 C 소스 코드가 포함된 파일이다.
컴파일러는 이 파일을 입력으로 받아 기계어로 번역된 어셈블리 코드를 생성한다.
이 어셈블리 코드는 test.s 파일에 저장된다.
어셈블러(assembler) 단계:
test.s 파일에는 어셈블리 코드가 포함된 파일이다.
어셈블러는 이 파일을 입력으로 받아 기계어로
번역된 오브젝트 코드(object code)를 생성하고 이 오브젝트 코드는 test.o 파일에 저장된다.
링커(linker) 단계:
test.o 파일은 컴파일러에 의해 생성된 오브젝트 코드 파일이다.
링커는 이 파일에 라이브러리 파일 등을 추가하여 실행 가능한 프로그램 파일을 생성한다.
이 실행 가능한 프로그램 파일은 test.exe 파일로 저장된다.
따라서, 전체 과정은 다음과 같다. 실제로 파일을 생성하여 출력해보자.
// test.c
#include <stdio.h>int main() {
printf("Hello, world!\\n");
return 0;
}
위 코드를 컴파일하여 실행 파일을 생성하는 과정에서 생성되는
각 파일들의 내용을 확인하겠다.
전처리기에 의해 생성된 test.i 파일의 내용을 출력하기 위해 다음 명령어를 실행한다.
cat test.i
출력 결과는 다음과 같다.
# 1 "test.c"# 1 "<built-in>"# 1 "<command-line>"# 1 "test.c"# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
...
int main() {
printf("Hello, world!\\n");
return 0;
}
컴파일러에 의해 생성된 test.s 파일의 내용을 출력하기 위해 다음 명령어를 실행한다.
cat test.s
출력 결과는 다음과 같다.
.file "test.c"
.text
.section .rodata
.LC0:
.string "Hello, world!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
...
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
.section .note.GNU-stack,"",@progbits
어셈블러에 의해 생성된 test.o 파일은
이진 형식으로 작성된 오브젝트 코드를 포함하고 있으므로,
cat 명령어로 직접 열어보는 것은 어렵다.
링커에 의해 생성된 test.exe 파일은 실행 파일이다.
따라서 해당 파일을 실행하면 "Hello, world!" 문자열이 출력되는걸 확인할 수 있다.
'네트워크와 CS' 카테고리의 다른 글
[Network] traceroute을 사용한 네트워크 실습 (5) | 2024.01.04 |
---|---|
[컴퓨터구조] 진법 변환의 실무 활용 예시 (1) | 2023.05.10 |
[소매컴싸] DataBase에 대해 (0) | 2022.12.22 |
[소매컴싸] Http와 https의 차이점에 대해 알아보자 (4) | 2022.12.22 |
[소매컴싸] 소피의 매일 컴퓨터사이언스 (0) | 2022.12.16 |