프로그래밍 언어로 작성한 소스코드가 컴퓨터 내부에서 명령어가 되고 실행하는 과정 알아보기❗
1️⃣ 고급 언어와 저급 언어
프로그램을 만들 때 사용하는 프로그래밍 언어는 컴퓨터가 이해하는 언어가 아닌 사람이 이해하고 작성하기 쉽게 만들어진 언어이다. 해서 컴퓨터는 이 언어를 이해하지 못한다. 이렇게 '사람을 위한 언어'를 고급 언어high-level programming language라고 한다. 알고 있는 대부분의 프로그래밍 언어는 고급 언어이다.
반대로 컴퓨터가 직접 이해하고 실행할 수 있는 언어를 저급 언어low-level programming language라고 한다. 컴퓨터가 이해할 수 있는 언어는 오직 저급 언어뿐이다. 고급 언어로 작성된 소스 코드가 실행되려면 반드시 저급 언어, 즉 명령어로 변환되어야 한다.
저급 언어는 두 가지 종류가 있다. 첫번째 기계어와 두 번째 어셈블리어가 있다.
기계어mechine code란 0과 1의 명령어 비트로 이루어진 언어이다. 즉, 기계어는 0과 1로 이루어진 명령어 모음이다. 컴퓨터는 0과 1로 이루어진 기계어를 이해하고 실행한다. 하지만 이진수로 나열하면 너무 길어지기 때문에 가독성을 위해 십육진수로 표현하기도 한다. 하지만 기계어는 사람이 읽으면 그 의미를 알기 쉽지 않다. 그래서 만든 언어가 어셈블리어assembly language이다.
어셈블리어는 0과 1로 이루어진 기계어를 읽기 편하게 만든 저급언어일 뿐이므로, 개발자가 어셈블리어를 이용해 복잡한 프로그램을 만들기는 쉽지 않다. 그래서 고급 언어가 필요하다. 고급 언어는 사람이 읽고 쓰기 편한 것은 물론이고, 좋은 가독성, 변수나 함수와 같은 편리한 문법을 제공하기 때문이다.
하지만 어떤 개발자로 되길 희망하는지에 따라 저급 언어의 중요성은 달라진다고 한다. 어셈블리어를 작성하거나 관찰을 할 일이 없는 개발자도 있고, 하드웨어와 밀접하게 맞닿아 있는 프로그램을 개발하는 임베디드, 게임, 정보 보안 분야 등의 개발자는 어셈블리어를 많이 이용한다.
그럼 왜❓ 위의 언급한 분야들이 어셈블리언어를 살펴볼까❓
위의 분야들의 개발자들에게 어셈블리어란 '작성의 대상'일뿐만 아니라 매우 중요한 '관찰의 대상'이기 때문이다. 어셈블리어를 읽으면 프로그램이 어떤 과정으로 실행하는지, 프로그램이 어떤 절차로 작동하는지를 가장 근본적인 단계에서 하나하나 추적하고 관찰할 수 있기 때문이다.
2️⃣ 컴파일 언어와 인터프리터 언어
고급 언어로 작성한 소스코드는 결국 저급 언어로 변환되어 실행된다고 했다. 그렇다면 고급 언어는 어떻게 저급언어로 변환이 될까❓
크게 두가지 방식이 있다. 컴파일 방식과 인터프리트 방식이 있다.
1) 컴파일 방식으로 작동하는 프로그래밍 언어를 컴파일 언어
2) 인터프리트 방식으로 작동하는 프로그래밍 언어를 인터프리터 언어라고 한다.
1. 컴파일 언어
컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어이다.
대표적인 컴파일 언어로는 C가 있다. 컴파일 언어로 작성된 소크 코드는 코드 천제가 저급 언어로 변환되는 과정을 거친다. 이 과정을 컴파일compile이라고 한다. 그리고 컴파일을 수행해 주는 도구를 컴파일러compiler라고 한다. 컴파일러는 개발자가 작성한 소스 코드 전체를 훑어보며 소스 코드에 문법적인 오류는 없는지, 실행하는 데 불필요한 코드는 없는지 등을 따지며 소스 코드를 처음부터 끝까지 저급 언어로 컴파일한다. 그래서 소스 코드 내에서 오류를 하나라도 발견하면 해당 소스코드는 컴파일에 실패한다.
컴파일이 성공적으로 수행되면 개발자가 작성한 소스 코드는 컴퓨터가 이해할 수 있는 저급 언어로 변환이 된다. 이렇게 컴파일러를 통해 저급 언어로 변환된 코드를 목적 코드object code라고 한다.
2. 인터프리터 언어
인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어이다. 대표적인 인터프리터 언어로 python이 있다.
소스 코드 전체가 저급 언어로 변환되는 컴파일러와 달리, 인터프리터 언어는 소스 코드를 한 줄씩 한 줄씩 차례대로 실행한다. 소스 코드를 한 줄씩 저급 언어로 변환하여 실행해 주는 도구를 인터프리터interpreter라고 한다. 인터프리터 언어는 컴퓨터와 대화하듯 소스 코드를 한 줄씩 실행하기 때문에 소스 코드 전체를 저급 언어로 변환하는 시간을 기다릴 필요가 없다.
그리고 소스 코드 내에 오류가 하나라도 있으면 컴파일이 불가능했던 컴파일 언어와는 달리, 인터프리터 언어는 소스 코드를 한 줄씩 실행하기 때문에 소스 코드를 한 줄씩 실행하기 때문에 소스 코드 N번째 줄에 문법 오류가 있더라도 N-1번째 줄까지는 올바르게 수행된다.
또한, 일반적으로 인터프리터 언어는 컴파일 언어보다 느리다. 컴파일을 통해 나온 결과물, 즉 목적 코드는 컴퓨터가 이해하고 실행할 수 있는 저급 언어인 반면에 인터프리터 언어는 소스 코드 마지막에 이를 때까지 한 줄 한 줄씩 저급 언어로 해석하며 실행해야 하기 때문이다.
✅ 컴파일 언어와 인터프리터 언어는 딱 구분할까?
C와 C++과 같이 명확하게 구분할 수 있는 언어가 있는 반면에 대표적으로 인터프리터 언어로 알려진 python도 컴파일을 하지 않는 것은 아니며, Java의 경우 저급 언어가 되는 과정에서 컴파일과 인터프리트를 동시에 수행한다.
즉, 하나의 프로그래밍 언어가 반드시 둘 중 하나의 방식으로만 작동하는 것은 오개념이다. 컴파일이 가능한 언어라고 해서 인터프리트가 불가능하거나, 인터프리트가 가능한 언어라고 해서 컴파일이 불가능한 것은 아니다.
따라서 모든 프로그래밍 언어를 이분법으로 분리하기보다는 '고급 언어가 저급 언어로 변환되는 대표적인 방법에는 컴파일 방식과 인터프리트 방식이 있다'정도로 생각하자.
참고자료 -
혼자 공부하는 컴퓨터구조 + 운영체제 / 한빛미디어
image -
'CS' 카테고리의 다른 글
[CS] ALU와 제어장치 (0) | 2023.01.31 |
---|---|
[CS] 다양한 주소 지정 방식 (0) | 2023.01.19 |
[CS] 명령어의 구조 (0) | 2023.01.17 |
[CS] 0과 1로 문자를 표현하는 방법 (0) | 2023.01.12 |
[CS] 0과 1로 숫자를 표현하는 방법 (0) | 2023.01.10 |