본문 바로가기
자동차 임베디드 SW/잡

컴퓨터 프로그램의 개념(컴파일.링크.빌드) 이해

by 존버매니아.임베디드 개발자 2021. 11. 14.
반응형

컴파일.링크.빌드의 개념
로더의 개념.  
Cache와 TLB의 개념

등등은
kocw 사이트에 있는 고려대학교 최린 교수님의
2019년 컴퓨터구조 강의를 공부한 내용을 정리하였다. 아래는 강의 링크 및 목차
http://www.kocw.or.kr/home/cview.do?cid=26adea597863b523

컴퓨터구조

컴퓨터의 구성 요소인 프로세서와 메모리, 입출력 장치의 동작원리와 내부 구조에 대하여 학습한다.

www.kocw.net

시간 있으면 해당 강의보면 어려운 내용 없이 이해가 잘 된다.
근데 일일이 다시 보기 귀찮으니까 대강의 개념만  블로그에 정리하려함.





sw는 컴퓨터가 수행할 수 있는 명령어들을 나열해놓은 것이다.

컴퓨터는 cpu를 갖고있는데 cpu는 저마다 고유의 instruction set을 갖고 있다. 이것은 cpu 제조사에서 정해서 만드는 것이기 때문에 우리가 고를 수 있는 문제가 아니다.

cpu architecutre 문서를 보면 해당 cpu의 instruction set을 볼 수 있다.
이런 명령어들은 어셈블리어 형태로 소개된다.
ex) mov. add. addi. store. load 등등


low 레벨 언어로 알려져있는 c언어도 어셈블리어보다는 high 한 개념이다. cpu는 c언어를 해석할 수 없다. cpu가 해석할 수 있는 명령은 오직 자신의 instruction set(어셈블리명령) 뿐이다.

그래서 c언어로 코딩을 하면 우리는 컴파일을 해서 이것을 어셈블리.기계어 형태의 명령으로 바꿔줘야 한다.

---------------
우리가 만든 .c 파일을 컴파일(빌드)하면 우선 컴파일러는 오브젝트 파일이라는 것을 만든다.
test1.c
test2.c
를 빌드하면 test1.o test2.o 가 만들어진다.
오브젝트 파일은 아직 완전하게 컴파일 된 파일이 아니라 불완전하게 컴파일 된 파일이고 그래서 아직은 실행가능한 파일이 아니다.

오브젝트 파일에는 code(txt) data bss 영역으로 구분되어 정보가 담겨있다.
오브젝트 파일이 아직 불완전한 이유는 메모리주소 정보를 아직 갖고 있지 않기 때문이다.

왜냐면 오브젝트 파일을 만들때는 각각의 파일 단위로 컴파일을 하기 때문에, 하나의 프로그램 안에 최종적으로 몇개의 c코드파일이 포함되는 것인지 알 수가 없고. 따라서 구체적인 메모리주소 할당을 오브젝트 파일을 만드는 과정에서는 할 수가 없다.
무슨말이냐면 예를 들어 test1.c에 func1이 정의되어있고 test2.c에 fun2가 정의되어있을 때,
만약 오브젝트 파일을 만드는 단계에서 각 function들의 주소를 확정해버리면 fun1과 fun2가 같은 메모리주소를 할당받게되는 불상사가 생길 수 있을 것이다. 앞에서 말했든이 오브젝트 파일을 만드는 단계에서는 파일 하나만을 생각하고 다른 파일의 존재여부를 생각하지 않기 때문이다.


그래서 test1.o 오브젝트 파일을 열어보면 코드와 데이터에 심볼들이 있는것을 볼 수 있다. 예를 들면
call fun1
call fun2
이런식으로 적혀있게 된다. 이때 fun1 fun2가 심볼이다.
심볼이란 sw안에서 자신의 고유한 메모리주소를 할당 받을 수 있는 대상을 말하며, 전역변수.static변수.함수가 심볼의 대표적인 예시이다.
근데 이러한 심볼들이
fun1. fun2 가 이렇게 글자로 적혀 있을게 아니라 실제로 해당 function이 메모리상에 위치하는 메모리 주소값으로 바껴야 실행가능한 파일이 된다.
근데 오브젝트 파일 단계에서는 그게 아직 확정이 안되서 위와같이 불완전한 파일 형태로 있게된다.


이렇게 오브젝트 파일들이 만들어지고나면 다음으로는 링커가 링킹을 해야한다.
링커는 오브젝트 파일들을 input으로 받아서,
code data bss 영역의 데이터들을 각각 받아서 취합한다.

test1.o의 code영역과 test2.o의 코드영역
test1.o의 data영역과 test2.o의 data영역
test1.o의 bss영역과 test2.o의 bss영역

그리고 이제서야 링커맵 정보를 바탕으로 심볼에 메모리주소를 할당한다.
이렇게 링킹 과정을 거치고나면 오브젝트 파일에 존재하던 심볼들은 구체적인 메모리 주소값을 갖게 된다.

따라서, 아까 test1.o 파일에
call fun1
call fun2

call 0x12345678
call 0x1234567c
이런식으로 변경된다.
따라서 이제야 완전히 실행가능한 파일이 되는 것이다.

한편, test1.c와 test2.c 에서 어떠한 라이브러리 파일을 사용하는 경우. 라이브러리 파일도 링킹 단계에서 같이 링크가 되어야한다.



반응형