어셈블러와 컴파일러의 차이

시스템 소프트웨어는, 하드웨어 리소스를 관리하며 컴퓨터 시스템의 작업들을 돕는 여러 프로그램들을 의미하며, 사용자들이 응용 소프트웨어의 작동과 이용에 집중할 수 있게 해준다.

여러 응용 소프트웨어의 실행 등을 관리하는 운영체제도 시스템 소프트웨어의 한 종류이고, 그 외로도 파일 시스템, 텍스트 에디터, 컴파일러, 어셈블러, 로더 등 많은 것들이 있다.


기계어, 어셈블리어

우리가 어떤 프로그램을 실행시킨다는 것은, 해당 프로그램을 동작시킬 명령어들이 메모리에 올라간 뒤, cpu가 명령어들을 읽어오면서 처리를 하며 컴퓨터의 다른 자원들에게 어떤 동작을 하게끔 만드는 것이다.

컴퓨터는 0과 1로만 이루어져있기 때문에, 이 때 cpu가 읽어들이는 명령어 역시 0과 1로만 이루어져있다.

그러나 우리가 흔히 사용하는 C++,Java,Python과 같은 프로그래밍 언어들로 프로그래밍을 할 때는 0과 1로 코드를 작성하지 않는다.

이진법 명령어는 기계가 이해하기 편하지, 사람이 이해하기는 굉장히 불편하기 때문이다. 아래의 명령어를 보고 이해할 수 있는 사람은 없을 것이다.

001001 11101 11101 1111111111111000
001000 00001 00000 0000000000001010
001000 00001 00001 0000000000000010
101011 11101 00001 0000000000000000
001000 00010 00001 0000000000000100
101011 11101 00010 0000000000000100
001001 11101 11101 0000000000001000

그래서 사람이 읽을 수 있는 언어로 만들어진 것이 어셈블리언어이다.

어셈블리어는 0과 1로 이루어진 해당 컴퓨터의 기계어와 일대일 대응이 되는 프로그래밍 언어로, 실행 속도나 자원 관리, 최적화 측면에서는 기계어와 사실상 똑같으면서도 코드 작성을 간편하게 할 수 있다(물론 기계어와 대비했을 때).


어셈블러

그러나 어셈블리어 역시 사람이 이해하는 언어로 만들어지기 때문에, 어셈블리어로 작성된 파일을 기계어에 해당하는 목적 코드로 바꾸는 작업이 추가적으로 필요한데, 이러한 일을 수행하는 시스템 소프트웨어가 바로 어셈블러이다.

즉, 프로그래머가 어셈블리어로 코드를 작성하면, 어셈블러라는 시스템 소프트웨어가 어셈블리 명령어와 일대일 대응이 되는 기계어 코드로 변환시켜 cpu가 실행시킬 수 있게 한다.

그러나 cpu마다 사용하는 기계어가 다르기 때문에, 이러한 어셈블리어와 기계어 등 자원에 직접 접근하는 low-level한 언어들은 기계에 종속적이라고 표현한다.

특정 컴퓨터에서 작성했던 어셈블리 코드가 잘 작동한다고 하더라도, 다른 컴퓨터에서 같은 코드를 실행시킨다면 해당 cpu가 이해하지 못하는 명령어가 되는 것이다.


컴파일러

같은 프로그램이지만 컴퓨터마다 다 다른 기계어(어셈블리어) 코드를 작성해야한다는, 기계에 종속적인 문제를 해결하기 위해 등장한 것이 C언어이다.

어셈블리어보다 더더욱 인간이 이해하기 쉬운 언어로 작성할 수 있으며, 같은 코드로 다른 cpu에서 똑같이 실행시킬 수 있게 해준다.

c언어는 컴파일러라는 시스템 소프트웨어와 함께 등장했는데, 컴파일러는 특정 프로그래밍 언어로 작성된 파일을 다른 프로그래밍 언어로 옮기는 시스템 소프트웨어이다.

변환하려는 파일을 소스 코드라고 하고, 변환되어 출력된 파일은 목적 코드라고 한다. 일반적으로 고급 프로그래밍 언어를 어셈블리어로 변환시킨다.

즉, c언어로 작성한 소스코드를 컴파일하면 어셈블리어 목적 코드로 변환되고, 어셈블러가 이러한 목적코드를 기계어 목적 코드로 바꿔 최종적으로 cpu가 이해할 수 있는 기계어가 된다.


다른 시스템 소프트웨어

이후에도 여러 목적 코드들을 서로 묶어 실행파일을 만들어주는 링커가 있다.

어떤 하나의 완성된 프로그램을 만들기 위해서, 서로 다른 소스코드들을 참조하면서 프로그램을 작성하게 되는데, 이 소스코드들이 각각 목적파일(c언어를 컴파일한 경우 .o)이 되고, 이런 목적파일들을 서로 연결해주는 것이다.

링커를 통해 최종적으로 실행할 프로그램에 대한 명령어 집합이 만들어지게 되면, 이를 메모리에 올려 cpu가 읽어 수행하게끔 해야 하는데, 이를 로더라는 시스템 소프트웨어가 수행한다.