cpu마다 각자 자신이 이해할 수 있는 기계어코드가 정해져있다.
이것은 sw적으로 configure가 불가하고 해당 hw를 만들때 처음부터 그렇게 정해져 있는 것이다.
low level 언어중 하나인 c언어 조차도 기계어는 아니다. 따라서 c언어로 코딩을 한 sw는 컴파일 과정을 통하여 기계어코드로 바뀌어야한다.
c언어로 작성된 코드를 컴파일하면 완전한 기계어 코드가 아닌 object 파일이 생성된다.
(확장자 .o 파일)
오브젝트 파일에는 기계어 코드. 초기화 된 전역변수. 초기화되지않은 전역변수들이 각각
.txt 섹션
.data 섹션
.bss 섹션 으로 구분되어 나열된다.
이 때 오브젝트 파일에는 아직
기계어코드와 전역변수와 같은 데이터가 정확히 몇번지의 메모리어드레스에 할당될 것인지는 정해지지않은 상태이다.
한편, 일반적으로 sw를 작성할 때 모든 내용을 하나의 c파일에 작성하지않고 여러 개의 c파일에 나누어 코딩한 후 한꺼번에 빌드하여 하나의 실행파일을 만들게된다.
그러면 abc.c 파일에서
fun1이라는 함수를 호출하는데, 이 때 fun1은 abc.c가 아닌 abcd.c 파일안에 정의되었을 수 있다. 또한 abc.c에서 extern int var이라는 변수를 참조해 올 수도 있다.
이러한 상황에서 abc.c 파일을 컴파일하면
fun1을 call 해야하는데 fun1의 주소정보를 모르기 때문에 기계어코드를 완성하기에는 정보가 부족하다.
그래서 abc.o 파일에서는
call fun1 이라고 불완전한 기계어 코드가 들어가있다.
이 때 fun1을 우리는 심볼이라고 부른다.
심볼이란 c파일들을 빌드했을때 자신의 메모리 어드레스를 별개로 부여받을 수 있는 것들을 말한다.
대표적으로 함수이름.전역변수 이름.static 변수 이름등이 있다.
그러면, 실제로 실행가능한 완전한 코드가 되려면 컴파일 후에 한가지 작업을 더 거쳐야한다.
그것이 링킹이고, 링킹을 해주는 sw가 링커이다.
일반적으로 우리가 사용하는 개발환경(IDE)에서 빌드버튼을 누르면 컴파일 뿐만 아니라 이 링킹과정까지 한번에 수행된다.
그래서 visual studio에서 코딩을 한 후 빌드하면 하나의 exe 파일이 생성되는 것이다.
아무튼 링킹이 뭘 하냐면,
abc.o 파일 abcd.o 파일을 input으로 받아서
각 파일안에 있는 txt data bss 섹션을 섹션별로 모은다.
그리고 이것들에게 메모리주소를 실제로 할당해준다.
예를 들어 abcd.o에 정의된 fun1에 0x100번지의 주소를 할당해주는 식이다.
한편, 앞에서 abc.o에는 call fun1이라는 불완전한 기계어 코드가 있다고했는데, 이제 링커에 의해 fun1에 0x100 번지가 할당되었으니
call fun1 기계어코드를 call 0x100 으로 바꿔서 완전한 기계어 코드를 완성시켜준다.
또한, 이렇게 abc.c 와 abcd.c파일 외에도
라이브러리 형태로 이미 만들어져있는 파일들을
abc.c 또는 abcd.c 에서 참조한다면,
링킹과정에서 이러한 라이브러리 파일들도 같이 링킹하게 된다.
아무튼 이러한 과정을 거쳐서
c언어로 작성됐던 코드가
기계어 코드, 데이터로 변환이 되고
그 각각에게 메모리주소가 할당되어 하나의 실행가능 sw가 완성되게 된다.
'컴퓨터공학' 카테고리의 다른 글
가상메모리.페이지2 (0) | 2020.08.31 |
---|---|
로더.가상메모리.페이지.세그멘테이션 (0) | 2020.08.31 |
dll 파일. 다이나믹 링킹 (0) | 2020.08.30 |
로더 (0) | 2020.08.30 |