728x90
반응형


컴퓨터를 실질적으로 작동시키는 매우 중요한 정보는 뭘까?

바로 '명령어'이다. 컴퓨터는 명령어를 처리하는 기계이다.

그럼 C, JAVA,Python,C#  등 프로그래밍 언어로 만든 소스 코드는 뭘까?

위 프로그래밍 언어로 만든 소스코드를 실행해도 컴퓨터가 잘 작동되는 이유는?

모든 소스 코드는 컴퓨터 내부에서 '명령어'로 변환되기 때문이다.

매우 중요한 이 개념을 학습해보자.

 

고급언어와 저급 언어


컴퓨터는 C,JAVA,Python,C#과 같은 프로그래밍 언어를 이해할까?

결론은 그렇지 않다.

개발자가 프로그램을 만들 때 사용하는 프로그래밍 언어는 컴퓨터가 이해하는 언어가 아니다.

프로그래밍 언어는 사람이 이해하고 작성하기 쉽게 만들어진 언어

즉, 고급 언어(high-level programming language)이다.

우리가 아는 대부분의 프로그래밍 언어가 고급 언어에 속한다.

그럼 반대로 컴퓨터가 직접 이해하고 실행할 수 있는 언어는 뭘까?

컴퓨터가 직접 이해하는 언어는 저급 언어(low-leve programming language)라고 한다.

컴퓨터가 이해하고 실행할 수 있는 언어는 오직 저급 언어뿐이다.

그래서 고급 언어로 작성된 소스 코드가 실행되려면 반드시 저급 언어

즉, 명령어로 변환되어야 한다.

저급 언어에는 두 가지 종류가 있는데 학습해보자.

 

기계어


기계어(machine code)란 0과 1의 명령어 비트로 이루어진 언어이다.

즉, 0과 1로 이루어진 명령어 모음이다.

이진수 기계어


컴퓨터는 위 그림과 같은 0과 1로 이루어진 기계어를 이해하고 실행한다.

다만 가독성을 위해 십육진수로 표현하기도 한다.

십육진수 기계어

기계어는 오로지 컴퓨터만을 위해 만들어진 언어이기 때문에

사람이 읽으면 그 의미를 이해하기 어렵다. 

그래서 등장한 저급 언어가 어셈블리어(assembly language)이다.

 

어셈블리어


기계어는 0과 1의 명령어 비트로 이루어져 있다.

어셈블리어는 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역해준다.

 

어셈블리어 언어는 우리가 아는 프로그래밍 언어와 다르게 생겼다.

0과 1로 이루어진 기계어를 읽기 편하게 만든 저급 언어일 뿐이므로

개발자가 어셈블리어를 이용해 복잡한 프로그램을 만들기란 쉽지 않다.

그래서 우리는 고급 언어가 필요하다.

가독성과 변수,함수와 같은 편리한 문법을 제공하기 때문이다.

그럼 굳이 저급 언어를 알아야 할까? 의문도 들지만 이유는 간단하다. 

어떤 개발자가 되길 희망하는지에 따라 저급 언어의 중요성이 달라지기 때문이다.

일반적으로는 하드웨어와 밀접한 임베디드 개발자, 게임 개발자,

정보 보안 분야 등의 개발자가 어셈블리어를 많이 이용한다. 

프로그램이 어떤 절차로 작동하는지 가장 근본적인 단계에서부터 추적하고 관찰이 가능하다.

어쨌든 프로그래밍을 시작한 입문자라면 반드시 알아두어야 한다.


고급언어 → 저급언어


고급 언어는 어떻게 저급 언어로 변환이 될까?

크게 두 가지 방식이 있다.

'컴파일방식''인터프리트방식'

컴파일 언어


컴파일 방식으로 작동하는 프로그래밍 언어를 컴파일 언어라고 한다.

컴파일 언어는 컴파일러에 의해 소스 코드 전체저급 언어로 변환되어 실행되는 고급 언어이다.

컴파일 언어(고급 언어) → 컴파일 → 저급언어

대표적인 컴파일 언어로 C가 있다.

그리고 컴파일(compile)은 컴파일 언어로 작성된 소스 코드를 저급 언어로 변환하는 과정을 뜻한다.

또한 컴파일을 수행해 주는 도구를 컴파일러(compiler)라고 하는데

컴파일러는 문법적 오류가 없는지~ 실행 가능한지~ 불필요한 코드는 없는지~ 등 따지며

소스 코드를 머리부터 발끝까지 저급 언어로 컴파일 한다.

컴파일이 성공적으로 수행되면 개발자가 작성한 소스 코드는 저급 언어로 변환 되는데

이렇게 컴파일러를 통해 저급 언어로 변환된 코드를 '목적 코드(object code)'라고 한다.

 

인터프리터 언어


소스 코드 한 줄씩 실행되는 고급 언어를 뜻하며 '파이썬(Phython)'이 대표적인 인터프리터 언어이다.

컴파일 언어처럼 소스 코드 전체가 저급 언어로 변환되는게 아니라!!

소스 코드 한줄~ 한줄~씩 차례로 실행한다. 

이렇게 한 줄씩 저급 언어로 변환하여 실행해 주는 도구를 '인터프리터(interpreter)'라고 한다.

인터프리터 언어는 컴퓨터와 대화하듯 소스 코드를 한 줄씩 실행하기 때문에 컴파일언어처럼

변환하는 시간을 기다릴 필요가 없다.

또 소스 코드내에 오류가 있으면 컴파일이 불가능했던 컴파일 언어와는 달리

한 줄씩 실행하기 때문에 소스 코드에 문법 오류가 있더라도 그 전까지는 잘 수행이 된다.

일반적으로 인터프리터 언어는 컴파일 언어보다 느리다. 

컴파일을 통해 나온 결과물, 즉 목적 코드는 컴퓨터가 이해하고 실행할 수 있는 저급 언어인 반면,

인터프리터 언어는 소스 코드 마지막에 이를 때까지 한 줄 한 줄씩 저급 언어로 해석하며 실행해야 하기 때문이다.

 

컴파일 언어와 인터프린터 언어의 구분


C, C++과 같이 명확하게 구분되는 언어가 있으나

요새는 언어 간의 경계가 모호한 경우가 많다.

대표적으로 Python도 컴파일을 하지 않는 것은 아니고 

JAVA의 경우도 저급 언어가 되는 과정에서 컴파일과 인터프리트를 동시에 수행한다.

따라서 저급 언어로 변환되는 대표적 방법에는 컴파일, 인터프리트가 있구나 정도로 알면 된다.

 

목적파일vs실행파일


이미지로 이루어진 파일은 이미지파일

텍스트로 이루어진 파일은 텍스트 파일

목적코드로 이루어진 파일은 '목적 파일'이다.

마찬가지로 실행 코드로 이루어진 파일은 '실행 파일'

윈도우의 .exe 확장자를 가진 파일이 대표적인 실행 파일이다.

목적 코드는 컴퓨터가 이해하는 저급 언어이다.

그리고 목적 파일과 실행 파일이 같은 의미는 아니다.

목적 코드가 실행 파일이 되기 위해서는 '링킹(lingking)'이라는 작업을 거쳐야 한다.

중요하니 예를들어 10단계로 낱낱이 살펴보자.

1. 컴파일 언어로 helper.c 와 main.c 라는 두 개의 소스 코드를 작성했다.

2. helper.c에는 'HELPER_더하기'라는 기능이 구현되어 있다.

3. main.c는 helper.c에 구현된 'HELPER_더하기' 기능과 프로그래밍 언어가 기본으로 제공하는

'화면_출력'이라는 기능을 가져다 사용한다.

4.두개를 컴파일하면 각각의 소스코드로부터 '목적 코드'가 생성된다.

5. 두 목적 파일은 각각 helper.o , main.o라고 지칭한다고 가정

6. 그럼 main.o는 저급 언어인데 바로 실행될까? 실행이 안된다.

7. main.o는 main.c 내용이 그대로 저급 언어로 변환된 '파일'일뿐이다.

8. main.c에 없는 'HELPER_더하기'나 '화면_출력'은 어떻게 실행하는지 모른다.

9. 따라서 main.o가 실행되려면 main.o에 없는 외부 기능들 즉, 8번의 기능을 연결 짓는 작업이 필요하다.

10. 이러한 작업이 '링킹(linking)'이다. 링킹 작업까지 거쳐야 비로서 하나의 실행 파일이 만들어진다.

 

마무리

  • 고급 언어 = 사람이 이해하기 위해 쉽게 만들어진 언어
  • 저급 언어 = 컴퓨터가 직접 이해하고 실행하는 언어
  • 저급 언어는 0과 1 명령어로 이루어진 기계어, 사람이 읽기 편하게 번역된 어셈블리어가 있다.
  • 컴파일 언어 = 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 언어
  • 인터프리터 언어 = 소스 코드 한 줄씩 저급 언어로 변환되어 실행되는 언어
반응형