본문 바로가기

교육 노트/통합 기초 강의

[기초지식] 2. 프로그래밍 언어는 어떻게 실행되는가? 컴파일러와 인터프리터

2018/09/01 - [교육 노트/통합 기초 강의] - [기초지식] 1. 프로그래밍 시작하기 전에 알아야될 기본 지식


C/C++, C#, JAVA, Python, javascript, PHP 내가 실제 프로젝트할떄 사용해본 언어만 해도 이정도이고

프로그래밍 언어는 이것보다 훨씬 많이 사용된다. 영어는 십년을 넘게 배워도 아직 잘 못쓰는데 프로그래밍 언어는 이제 왠만한 언어를 던져 두어도 함수형 처럼 새로운 개념이 나와도 그냥 저냥 사용할 만한 수준까지 배우는데 한달도 채 걸리지 않는 경우도 있고 같은 패러다임을 가지는 언어는 아예 프로젝트를 진행하면서 문법을 배우는 경우도 있다. 물론 처음부터 차근 차근 배우는것과 수준은 다르겠지만...

아무튼 이야기 하고싶은것은 프로그래밍 언어를 많이 아는것은 크게 자랑거리가 아니다. 아니 마스터했다고 하면 자랑거리겠지만..

입문자들이 처음 배울때 왠지모르게 다양한 언어를 만나보고 싶어하고 이유없이 언어를 확장하고 싶어한다.

그러나 열정을 가지는것은 좋은데 그것이 본질적인 실력향상을 가져와주지는 않는다.

단순히 여러 언어의 문법을 아는것보다 해당 언어가 어째서 이런방식을 사용하는지, 왜 이런한 방식으로 작동하는지 아는것이 더 중요하다고 생각한다.



1. 프로그래밍 언어가 기계어가 되는 과정, 실행되는과정

각각의 언어는 단순히 문법이 다르다 수준도 있지만 해당 언어들이 컴퓨터가 알아들을수있개 0101과 같은 기계어로 변역되는과정 자체가 다른경우도 존재한다.


대표적으로 컴파일 언어와 인터프리터 언어로 나뉘는경우

또 VM위에 돌아가는 언어와 그렇지 않은 언어 라고 볼수있다.


우선 프로그래밍 언어는 어떻게 기계어가 되는것일까?

컴퓨터는 프로그래밍 언어를 알지 못한다. 컴퓨터는 01010과 같은 기계어만 아는것이다.

0000101011101100011101101 머 이런 0과1의 조합이 들어오면 이것을 해석하는것인데

그럼 컴퓨터가 알아듣을려면 결국 0과 1의 조합으로 컴퓨터에게 주어야한다

근데 이렇면 우리같은 범인들을 절때 프로그램을 만들지 못한다..

0101로 프로그래밍이라니..

그래서 개발된것이 어셈블리 언어이다.

어셈블리는 기계어와 1대1 대응되는 프로그래밍 언어로

예를 들어 기계어 0101 메모리를 옮기는것으로 컴퓨터가 이해하므로  MOV 로 표현하자~ 이런식으로

인간들끼리 규칙을 정한것이다

0101 0010 1 이런한 기계어가 있으면 MOV exa 1 이런식으로 표현하자 라고 규칙을 정했다. (임의로 만든 규칙입니다)

그러면

MOV exa 1 이렇게 우리가 어셈블리어로 코딩을 하는것이다.

그렇면 이제 이걸 기계어로 바꾸어야 컴퓨터가 이해를 하는데

1대1 대응이었으므로 다시 기계어로 바꿀수가 있다.

그럼 어셈블리어 대응표를 보고 인간이 직접 바꾸어야할까?

똑똑하신 분들이 이렇게 MOV라는 텍스트가 오면 0101로 바꾸도록 프로그램을 이미 만들어 두었다 (처음 이 프로그램은 0101로 한땀한땀 만들었을것이다)

그래서 MOV exa 1이라는 텍스트를 일고 0101 0010 1로 다시 바꿔주는 "어셈블러" 프로그램을 통하여 우리는 어셈블리어로 코딩할수 있는것이다.


이렇게 해서 어셈블리어까지는 우리가 기계어로 바꿀수 있게 되었다.

그러면 다른 언어들은 어떻게 표현되는것일까?


어셈블리어도 그렇고 모든 다른 언어들도 그렇고

그냥 해당 언어의 문법에 맞게 작성된 문장일 뿐이다.

그냥 메모장에 안녕하세요~~적듯이

메모장에 C++/Java/Python 코드등이 적혀있을 뿐이다

그러면 파일명에 main.cpp, main.java, main.py 와 같이 뒤에 붙는 cpp, java, py 는 뭐냐고?

이건 그냥 사람이 이해하기 쉽게 하려고 붙여놓은 확장자이다, cpp붙었다고 뭐 어마어마한 파일이 아니라

걍 메모장으로 열면 C++ 코드가 적혀있는데

main (참고로 내용은 CPP로 작성되었습니다~~).txt

보다는

main.cpp

이게 더 이해하기 쉽고 간결하니까.. 그렇게 쓰는것이다.

이럼 이런 단순한 텍스트 파일이 프로그램으로 어떻게 바뀌는것일까?



컴파일 (Compile) 언어의 대표인 C/C++을 살펴보면

전처리기 -> 컴파일러 -> 링커 -> exe 파일 나옴!

여기서 전처리기가 컴파일 하기전에 처리해야될 내용들을 처리하여 (include, define 같은것) 우리가 만든 코드 자체를 수정해버린다.

그럼 이제 이 처리된 코드가 컴파일러에 들어가 어셈블리어를 거쳐 기계어가 나온다. 이과정을 컴파일이라고 하고

이 과정을 처리해주는 "프로그램" 이 컴파일러다. 즉 컴파일러도 프로그램이고 C++ 규칙에 맞게 나온 문장들을 미리 프로그래밍된 대로 처리해주는 프로그램이다. 해당 과정을 거치면

우리가 만든 C++ 코드가 기계어로 변역되어 기계어로 되어있는 목적파일이라는것이 나오게된다.

그러나 목적파일은 0101로 이루어져있지만 컴퓨터가 실행 시킬수 없다.

그이유를 간단히 설명하자면

목적코드에 적힌 내용은 [화면에 "Hello World"를 출력하시오] 라는 내용이 기계어로 변역된 내용이다.


그러나 해당내용이 기계어로 변역되서 이해는 하겠는데.. 문제는 컴퓨터가 출력이라는것을 어떻게 하는지 모르는것이다.

게임하다가 팀원들이랑 한글로 채팅한다고 말이 통하는 상대가 아닌것처럼. 기계어지만 할수는 없는 상황이다.


하지만 컴퓨터에 어떻게 출력하도록 하는지는 나도 모르지만

또 이미 똑똑하신 분들이 이미 다 만들어 놓았다

아~ 출력은 이렇게 이렇게 하면 되~ 라고 미리 만들어둔 파일이 라이브러리이고

우리가 만든 기계어에서 "출력" 이라는 부분을 이 라이브러리와 연결(link) 하여 출력하는 방법까지 알고있는 기계어로 된 파일이

실행파일 (.exe) 이고 이것이 우리가 만들어낸 "프로그램" 이 되는것이고 라이브러리와 연결해주는 "프로그램"이 링커이다


이것이 프로그래밍언어가 기본적으로 프로그램이 되는 과정이다.


JAVA와 같은 경우

일반적으로 위 과정을 따르지만

컴파일을 하고 나면 목적 코드가 아닌 바이트 코드라는것이 나오게 된다.

C++과 같은 경우 C++로 만든 프로그램은 해당 운영체제 혹은 CPU에 맞추어 생성되어

OS 가 바뀌면 실행할수없다. 즉 윈도우에서 만든 프로그램은 리눅스에서 실행 할 수 없는것이다. (exe파일은 리눅스에서 실핼 할 수 없음)

따라서 리눅스에서 돌아가는 프로그램을 만들기위해서는 리눅스 에서 돌아가도록 컴파일 과 링킹 과정을 또 처리해야하는데

이게 그냥 되면 좋지만

라이브러리가 다르거나 하는 문제때문에 C++코드를 변경해야하는 일이 생길수도있고 생각지도 못한 동작이 될수도 있다.


JAVA는 write once run everywhere 라는 것을 모토로

아ㅡㅡ 한번 만들어 주면 됫지 또 만들어줘야 해? 그냥 다 돌아가게 하자!

라고 생각하여

각각에  운영체제에 맞게 가상머신이라는 프로그램을 만들어두고

그 위에서 우리 프로그램이 돌아가도록 해버리면

가상머신은 JAVA 개발자들이 만들어주고

JAVA를 사용하는 개발자는 OS 신경쓰지말고 프로그래밍 할수있다.


바이트 코드역시 [화면에 "Hello World"를 출력하시오] 와 같은 내용을 담고 있는데

JAVA와 같이 VM (가상머신)을 사용하는 언어는 여기서 링커가 라이브러리와 연결하여 exe파일이 나오는것이 아니다.

걍 바이트 코드를 읽어서 프로그램을 실행시키는 가상머신이라는 "프로그램"을 운영체제에 맞게 미리미리 만들어 두어서

각각 운영체제에서 자바 코드가 똑같이 동작하도록 미리 만들어지 자바 가상머신을 설치하면 이 가상머신이 다시 바이트 코드를 읽고

프로그램으로 실행시키는것이다.

이렇게 되면 프로그램이 실행되는데 한단계가 더 생기게 되는것인데

이로인하여 JAVA는 C/C++ 과같은 언어보다 느리다는 단점을 가지게 된다. (따라서 속도에 민감한 프로그램은 C/C++로 프로그래밍 된다)

하지만 코딩 못한 C++ 코드가 잘짠 JAVA보다 느리게 동작할수 있으므로... 개발자는 어디서 돌아갈지 신경쓰지말고

개발이나 열심히 하면 된다.



Python의경우 인터프리터(interpreter) 언어이다

아예 구조가 다른데

지금까지는 컴파일러 라는 프로그램을 통하여 컴파일 과정을 거치게 되었다.

여기서 컴파일러는 모든 코드를 다 읽고 최적화된 기계어 코드를 생성하게 되는데

인터프리터는  해석기, 통역사 라는 의미를 가지고 있다. 통역사는 모름지기 실시간으로 번역해서 알려줘야 하는법.

인터프리터는 한줄 한줄 읽어서 그때 그때 기능을 수행한다.


중요한 것은 인터프리터 역시 컴파일러, 링커 처럼 "프로그램" 이다.

즉 파이썬의 언어 규칙을 해석할수있도록 만들어진 파이썬 인터프리터 라는 "프로그램" 을 다운받으면

그 인터프리터 프로그램을 작동시키고 파이썬 코드를 한줄씩 입력시키고

인터프리터가 그 내용을 실시간? 해석하여 컴퓨터에게 알려주는것이다.


이해하기 쉽게 이야기하자면 파이썬은 인터프리터라는 프로그램 위에서 돌아간다고 할 수 있다.


728x90