학사 나부랭이

Operating System - Compile to execute 본문

Dot-Gabi/Operating System

Operating System - Compile to execute

태양왕 해킹 (14세) 2021. 4. 6. 19:56

0. Pre-processor(전처리기)가 컴파일 전에 코드를 적절한 상태로 처리해요. #로 시작하는 #include <stdio.h> 같은 전처리기 구문으로 헤더 파일을 불러오거나 기호 상수를 정의해서 코드 상에 필요한 내용을 먼저 채워주는 역할을 해요.

1. Compiler가 각 소스 파일들을 컴파일해서 .o(obj)파일로 변환하고

2. Linker가 여러 오브젝트 파일을 하나의 오브젝트 파일로 묶어요. 이때 생긴 하나의 오브젝트 파일이 우리가 보는 .exe파일, 실행 파일이에요.

3. 이 파일을 실행시키면 운영체제의 Loader에 의해 메모리에 적재되어요.

 

Compiler

 프로그래머가 C등의 문법에 의해 작성한 소스를 기계어로 번역해서 위의 오브젝트 파일에 넣는 역할을 해요. 그리고 각각 소스 파일에 대한 Symbol table을 생성하죠.

 

Linker

 이렇게 기계어로 번역되었다고 바로 실행할 수는 없는 게 운영체제의 요건에 맞춰 형태를 조금 바꾸고 StartUP이라는 추가 코드를 작성해줘야 해요. Text section, data section, ZI section 등의 베이스 주소를 결정하는 등 오브젝트 파일에 이런 처리를 해서 실행파일로 만드는 역할을 하는데 이 과정을 Build라고 해요.

 

Loader

 실행 파일을 읽고 메모리에 오브젝트 파일의 내용들을 적재(Program Counter를 실행 파일의 엔트리 포인트로 설정)시켜요. 이를 수행하기 위해서는 다음과 같은 기능이 필요한데요. 먼저 오브젝트 파일이 적재될 메모리의 공간을 확보하는 할당, 여러 오브젝트 또는 외부 기호를 참조할 때 이들을 연결, 오브젝트를 실제 메모리에 맞춰 상대 주소를 절대 주소로 수정해주는 재배치, 실제 프로그램과 데이터, 모듈을 메모리에 읽어 들이는 적재가 있어요.

 

오브젝트 파일

 오브젝트 파일은 프로그램의 특징에 따라 각각의 Section으로 구분되는데 프로그램의 코드가 저장되는 Text section, 초기화된 전역 변수가 저장되는 Data section, 초기화되지 않은 전역변수가 저장되는 ZI(Zero Initialization) section(=Block Started by Symbol), 프로그램에서 사용하는 심벌에 대한 자료를 저장하는 Symbol table, 외부 심벌에 대한 처리를 위한 Relocation table이 있어요.

+) 변수 선언을 하고 값을 넣어 초기화를 하면 그 변수의 크기만큼 메모리를 사용하게 되어요. 그런데 초기화를 하지 않았으면 그냥 변수의 이름과 크기 같은 정보만 올려주면 되기에 ZI와 Data 영역이 구분되어요.

 

Section

 컴파일러를 거쳐 만들어진 오브젝트 파일에는 여러 Section이 존재하는데 오브젝트 파일을 구성하는 유닛이나 데이터를 묶어놓은 단위를 뜻해요. 이 섹션들은 이후 메모리에 적재될 세그먼트라는 독자적인 영역을 가져요. 각 섹션에는 함수 이름, 변수 이름 등 여러 심벌이 존재하고 그 안에서의 자신의 위치인 offset을 주소로 가져요.

 

Symbol table

 int data1; 여기서 사람은 int형 변수 data1을 문자열로서 선언해주고 기억하지만 컴퓨터는 숫자로만 기억을 하죠. 그래서 data1이라는 문자열과 그 숫자를 매칭시키기 위해 사용되는 것이 심벌 테이블이에요.

컴파일러가 어셈블리어로 번역
번역할 때 쓰이는 심볼 테이블, 0x0은 Cross reference의 주소예요.

변수가 선언되면 테이블을 생성해 변수의 타입과 이름, 주소를 생성하죠. 그리고 변수 초기화를 하면 심볼 테이블에서 심벌 이름으로 변수를 찾아 해당 주소에 값을 넣어요. 즉, 컴파일러가 어떤 심벌을 읽게 되면 그 심벌에 해당하는 진입점을 테이블에 넣고 그 심벌의 주소를 알 수 있으면 Section 주소와 offset으로 채워요. 이런 주소가 Internal reference라고 해요. 컴파일러가 소스파일에 대한 심볼 테이블을 만들 때 각각 만들기 때문에 외부 심벌에 대한 주소를 확정할 수 없어요. 그래서 two-path 컴파일 과정(컴파일러 + 링커)으로 재배치 테이블을 이용해서 외부 심벌에 대한 주소를 특정해요.

 

Relocation table

 전체 Section의 위치가 바뀌어도 PC에서의 상대적인 거리는 바뀌지 않기 때문에 section 시작 주소 + offset 주소로 파악된 심볼 주소(Internal reference)를 PC 상대 주소로 변환해요. 그리고 Cross refernce는 주소를 모르기 때문에 0으로 체크 후 internal reference를 먼저 처리한 후 링커가 해결해서 추가적으로 기입해요.

 

Cross reference

 이에 대한 정보는 여러 오브젝트 파일에 흩어져 있으므로 각 오브젝트 파일을 다니며 주소를 수집하고 그 주소를 이용해서 실제 주소로 대체해요. 링커가 이 문제를 해결하려면 path를 두 개 이상 사용해야 링킹이 가능하죠.

'Dot-Gabi > Operating System' 카테고리의 다른 글

Operating System - Boot loader  (0) 2021.05.14
Operating System - Memory management  (0) 2021.04.06
Operating System - Memory  (0) 2021.04.02
Operating System - Kernel  (0) 2021.04.02
Operating System - Opening & Systems  (0) 2021.04.02
Comments