일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- 재배치
- 대상파일
- 구문트리
- 정처기 공부법
- 백준
- 코드포스
- column space
- 정처기 실기 공부법
- 다이나믹 프로그래밍
- linear algebra
- unity
- c++
- 다익스트라
- Rust
- 정보처리기사 2025 1회 실기 벼락치기
- 벡터
- 정보처리기사 실기 벼락치기
- eigenvalue
- 정처기 실기 벼락치기
- 링커
- 선형대수학
- 행렬
- vector
- matrix
- 알고리즘
- CS정리
- 컴퓨터밑바닥의비밀
- 스레드전용저장소
- rust 스터디
- 컴파일러
- Today
- Total
개발_기록용
[컴퓨터 밑바닥의 비밀 내용정리] 1.3 컴파일러의 동작원리 본문
0. 들어가며
- 굉장히 감명깊게 읽었던 [컴퓨터 밑바닥의 비밀] 책의 내용을 돌아보기 위해 정리글을 작성한다.
- 전공자로 어느정도 안다고 생각한 내용들에서도 부족한 부분이 보여 책을 다시 읽어보며 정리하고자 한다.
https://link.coupang.com/a/cdaqFv
컴퓨터 밑바닥의 비밀:컴퓨터 시스템의 본질을 알면 코드의 실마리가 보인다 - 보안과 해킹 | 쿠
쿠팡에서 4.3 구매하고 더 많은 혜택을 받으세요! 지금 할인중인 다른 3 제품도 바로 쿠팡에서 확인할 수 있습니다.
www.coupang.com
"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
(본문 소개 링크로 도서 구입 시 일정액의 수수료를 제공받습니다.)
1. 주제
아래와 같이 간단한 코드를 작성한다고 하자.
int a = 1;
Int b = 2;
while (a < b)
{
b = b - 1;
}
우리가 앞서 살펴본 바에 따르면 궁극적으로
컴파일러는 이 코드를 기계어로 구성된 실행파일로 만들어주는 역할을 한다.
방금 쓴 코드를 인간의 관점에서 해석해보자.
인간의 관점에서 해석
a라는 변수에 1을 할당한다.
b라는 변수에 2를 할당한다.
a < b 라면 b가 1씩 줄어든다.
a < b 가 더 이상 성립하지 않을 때까지 앞의 문장을 반복한다.
: 그러나, CPU는 이런 추상적인 표현을 이해하지 못한다.
컴파일러는 먼저 각 항목을 잘게 쪼갠다.
이때 각 항목이 가지고 있는 추가정보를 함께 묶어 관리한다.
(여기서 각 항목이 갖고 있는 추가정보를 ‘토큰’이라 한다.)
컴파일러 관점에서 분석
int a = 1;
T_Keyword int
T_Identifier a
T_Assign =
T_Int 1
T_Semicolon ;
이런식으로 컴파일러는 소스코드 각 항목을 잘게 쪼개어 토큰을 찾는다.
=> 이 과정을 ‘어휘분석’(Lexical Analysis) 또는 ‘스캐닝’이라 한다.
2. 토큰을 통해 컴파일러는 무엇을 알 수 있을까?
토큰만 봐서는 아무 의미도, 뜻도 알 수가 없다.
우리는 앞서 코드는 구문에 따라 작성되어야 함을 확인한 바 있다.
그럼 ‘컴파일러가 구문에 따라 토큰을 처리한다’는 것은 무슨 의미일까?
다시, 앞에서 살펴본 코드에서 while문을 다시 살펴보자.
while(a<b)
{
b = b-1;
}
컴파일러가 while 키워드의 토큰을 찾으면
다음 토큰이 ‘(’라는 것을 알고 있는 상태로 기다리게 된다.
하지만 다음 토큰이 while 키워드에 필요한 토큰이 아니라면
컴파일러는 문법오류(syntax error)를 보고한다.
이런 해석 과정을 파싱(parsing)이라 한다.
컴파일러가 구문에 따라 해석해낸 ‘구조’는 트리로 표현한다.
위의 while 문은 아래와 같은 트리로 표현될 수 있다.
구문 규칙에 따라 토큰을 해석한 후 생성된 트리가 ‘구문 트리’이며
이 트리를 생성하는 전체 과정이 ‘구문 분석’이다.
그리고 구문 트리가 생성되고 나면, 우리는 구문 트리에 이상이 없는지 확인해야 한다.
예를 들어, 정수값에 문자열을 더하면 안되고,
비교 기호 좌우에 있는 값의 형식이 다르면 안된다.
=> 이 단계를 통과하면 프로그램에 이상이 없으니
‘컴파일 오류가 없다’가 증명되는데, 이 과정을 의미 분석(semantic analysis)이라 한다.
3. 구문트리를 기반으로 ‘중간 코드’ 생성하기.
의미분석이 끝나면 컴파일러는 구문트리를 탐색한 결과를 바탕으로
좀더 다듬어진 형태인 중간코드(Intermediate Representation Code, IR Code)를 생성한다.
a = 2
b = 1
goto B
A : b = b - 1
B : if a < b goto A
: 앞의 구문 트리를 토대로 만들어진 중간 코드.
그리고 중간코드를 생성하면 컴파일러는 이를 어셈블리어 코드로 변환한다
: 앞의 중간코드를 기반으로 만들어진 어셈블리어 코드.
4. 컴파일 과정이 끝나면..
하나의 소스코드 파일인 code.c를 컴파일하면
이 과정을 거쳐 생성된 기계 명령어 데이터는 code.o라는 파일에 저장된다.
이때, ‘.o’ 확장자를 갖는 파일을 대상파일(object file)이라 한다.
=> 즉, 모든 소스파일은 각각의 대상파일이 있다.
=> 따라서, 프로젝트에 소스파일이 3개면 대상파일도 3개.
근데, 우리는 하나의 실행파일을 원한다.
=> 이 3개의 대상 파일을 하나로 합쳐주는게 ‘링커’의 역할이며
이 작업을 ‘링크’라고 한다.
'Computer Science' 카테고리의 다른 글
[컴퓨터 밑바닥의 비밀 내용정리] 1.5 정적 라이브러리와 정적 링크 (2) | 2025.02.07 |
---|---|
[컴퓨터 밑바닥의 비밀 내용정리] 1.4 링커의 일하는 방식 (0) | 2025.02.07 |
[컴퓨터 밑바닥의 비밀 내용 정리] 1.2 인터프리터(가상머신) (2) | 2025.02.04 |
[컴퓨터 밑바닥의 비밀 내용 정리] 1.1 구문 트리 (0) | 2025.02.03 |
[2024 정보처리기사 3회 필기] 1주일 벼락치기 합격 후기 (1) | 2024.07.07 |