프로그램을 만들 때 사용하는 프로그래밍 언어는 컴퓨터가 이해하는 언어가 아닌 사람이 이해하고 작성하기 쉽게 만들어진 언어이다. 컴퓨터는 이 언어를 이해하지 못한다. 이렇게 ‘사람을 위한 언어’를 고급 언어(high-level programming language)라고 한다.
반대로 컴퓨터가 직접 이해하고 실행할 수 있는 언어를 저급 언어(low-level programming language)라고 한다. 저급언어는 명령어로 이루어져 있고 컴퓨터가 이해하고 실행할 수 있는 언어는 오직 저급 언어 뿐이다. 그래서 고급 언어로 작성된 소스 코드가 실행되려면 반드시 저급 언어, 즉 명령어로 변환되어야 한다.
저급 언어에는 두 가지 종류가 있는데 바로 기게어와 어셈블리어이다.
우선 기계어(machine code)란 0과 1의 명령어 비트로 이루어진 언어이다. 다시 말해 기계어는 0과 1로 이루어진 명령어 모음이다. 컴퓨터는 0과 1로 이루어진 이 기계어를 이해하고 실행한다. 다만, 기계어를 이진수로 나열하면 너무 길어지기 때문에 가독성을 위해 십육진수로 표현하기도 한다.
그런데 위 기계어를 보면 무엇을 뜻하는지, 컴퓨터가 어떻게 작동하는지 이해하기 어려울 것이다. 왜냐하면 기계어는 오로지 컴퓨터만을 위해 만들어진 언어이기 때문이다. 그래서 등장한 저급언어가 어셈블리 언어이다.
어셈블리 언어는 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역한 언어이다. 어셈블리어는 0과 1로 이루어진 기계어를 읽기 편하게 만든 저급언어일 뿐이므로, 개발자가 어셈블리어를 이용해 복잡한 프로그램을 만들기란 쉽지 않다.
그래서 고급 언어가 필요한 것이다. 고급 언어는 사람이 읽고 쓰기 편한것은 물론이고, 더 나은 가독성, 변수나 함수 같은 편리한 문법을 제공하기 때문에 어떤 복잡한 프로그램도 구현할 수 있다.
“그러면 왜 저급언어를 알아야 할까?”라는 생각을 할 수 있을 것이다. 어셈블리어는 주로 하드웨어와 밀접하게 맞닿아 있는 프로그램을 개발하는 임베디드 개발자, 게임 개발자, 정보 보안 분야 등의 개발자가 많이 사용한다. 그리고 이러한 분야의 개발자들에게 어셈블리어란 ‘작성의 대상’일 뿐만 아니라 매우 중요한 ‘관찰의 대상’이기도 하다. 어셈블리어를 읽으면 컴퓨터가 프로그램을 어떤 과정으로 실행하는지, 즉 프로그램이 어떤 절차로 작동하는지를 가장 근본적인 단계에서부터 하나하나 추적하고 관찰할 수 있기 때문이다.
개발자들이 고급언어로 작성한 소스코드가 어떻게 저급언어로 변환될까? 여기에는 크게 두 가지, 컴파일 방식과 인터프리트 방식이 있다. 컴파일 방식으로 작동하는 프로그래밍 언어를 컴파일 언어, 인터프리트 방식으로 작동하는 프로그래밍 언어를 인터프리터 언어라고 한다.
1) 컴파일 언어
컴파일 언어는 컴파일러에 의해 소스코드 전체가 저급언어로 변환되어 실행되는 고급언어이다. 대표적인 컴파일 언어로는 C, JAVA가 있다.
이 컴파일 언어로 작성된 소스코드는 코드 전체가 저급언어로 변환되는 과정을 거치게 된다. 이 과정을 컴파일(compile)이라고 한다. 그리고 컴파일을 수행해주는 도구를 컴파일러(compiler)라고 한다.
컴파일러는 개발자가 작성한 소스코드 전체를 쭉 훑어보며 소스코드에 문법적인 오류는 없는지, 실행 가능한 코드인지, 실행하는 데 불필요한 코드는 없는지 등을 따지며 소스 코드를 처음부터 끝까지 저급 언어로 컴파일한다. 이때 컴파일러가 소스 코드 내에서 오류를 하나라도 발견하면 해당 소스코드는 컴파일에 실패한다.
컴파일이 성공적으로 수행되면 개발자가 작성한 소스코드는 컴퓨터가 이해할 수 있는 저급언어로 변환된다. 이렇게 컴파일러를 통해 저급언어로 변환된 코드를 목적코드(object code)라고 한다.
2) 인터프리터 언어