• 기계어와 어셈블리어와의 차이점
    •  
    • 컴퓨터 언어 (computer language) 란 무엇인가?
    • A 라는 사람이 B 라는 사람에게 일을 시키려면 어떤 일을 해야하는지 말이나 글로서 그 사람에게 전달해야한다. 이렇듯 누군가에게 일을 시키려면 어떻게 어떻게 일을 해 달라고 기술 해야만 한다. 예를 들어 복사집에 가서 복사를 맡길때 책의 어디부터 어디까지를 몇부 복사해달라고 말을 하게되면 복사집 아저씨는 그 말을 듣고 기억했다가 해당되는 일을 하게 된다.

      이와 마찬가지로 사람이 컴퓨터에게 특정 일 (예를 들면 게임이나 워드프로세서 작업 인터넷 접속등)을 시키려면 그 일을 어떻게 어떻게 해야한다고 세세하게 알려줘야 한다. 사람은 지능이 있어서 애매한 정보도 과거의 경험이나 스스로의 판단력을 이용 작업을 행할수 있지만 컴퓨터는 이런 지적인 능력이 없어서 아주 정확하게 기술을 해야만 한다.

      이때, 일을 기술하는 사람은 (보통 프로그래머 라고 함) 해당 CPU 가 어떤 명령을 알아듣는지 그리고 어떻게 기술해야 알아듣는지를 잘 알고있어야만 한다. CPU 를 만드는 회사는 사람이 기술한 일을 수행할수 있는 CPU를 만들기 위하여 필요한 명령어 및 필요한 레지스터를 정의하고 이를 구현한다. 그런데, 회사마다 구현 명령어및 레지스터가 다 다름으로 특정 CPU에게 일을 시키는 사람은 자기가 사용하는 CPU의 명령어 및 레지스터 등등에 대하여 자세히 알고 있어야 한다.

      CPU는 아주 정확히 기술된 사항만을 인식한다. 그러므로 CPU 제조사는 해당 CPU 가 어떤 명령어를 수행할수 있는지 또한 수행시 어떤 결과를 내는지를 세세히 프로그래머에게 알려주어야한다. 이렇듯 사람이 컴퓨터에게 일을 시키기 위해서는 컴퓨터가 이해할수 있는 명령어로 정확한 기술을 해주어야만 하는데 이러한 모든 언어를 컴퓨터 언어라고 한다.  

    • 기계어란 무엇인가?
    • 우리가 현재 사용하고 있는 대부분의 CPU는 디지탈 컴퓨터이다. 디지탈 로직에서 배운것처럼 디지탈 시스템은 오로지 0과 1만을 인식한다. 그러므로 특정 CPU에게 일을 시키고자 하는 사람은 오로지 1과 0으로서 일을 기술해 주어야만 한다. 이렇게 기술한 일은 해당 CPU 가 곧바로 이해하고 실행할수 있음으로 기계어라고한다.  

    • 왜 어셈블리어가 도입되었는가?
    • 다음은 인텔 8086 CPU 에게 일을 시키는 기계어중 하나이다.
       
      기계어
      16진수로 표현한 기계어
      어셈블리로 표현
      의미
      101110000111000100110001
      B87131
      MOV AX, 3171
      십진수 3171을 AX에 넣어라

      위의 예에서도 알수있듯이 사람이 기계어로 특정 CPU에게 일을 시키는것은 상당히 어려운 일이다. 의미를 알기어려운 0과 1로서만 이루어졌기 때문이다. 각 기계어를 사람이 알기쉬운 기호로 표시한다면 해당 CPU에게 일을 시키기가 훨씬 용이할 것이다. 이러한 이유로 어셈블리어가 도입되었다. 하지만 어셈블리어로 기술된것은 해당 CPU 가 직접알아들을 수 없음으로 이를 해당 CPU 가 알아들을수 있는 기계어로 번역해 주어야만한다. 이러한 번역 작업을 사람이 하게 된다면 이 또한 어셈블리어를 사용하는 장점이 사라진다. 그러므로 이러한 번역 작업을 수행하는 일을 하도록 만든 프로그램이 어셈블러 이다.

      이를 우리 사회와 비교해 보면 이와같다. 영어를 (기계어를) 할줄 모르는 한국 사람이 (사람이) 미국 사람에게 (컴퓨터에게) 일을 시키려면 영어를 (기계어를) 배워야만  한다. 영어가 (기계어가) 너무 어렵기 때문에 그냥 한국말로 (어셈블리어로) 기술하고 이를 통역 (번역) 해주는 사람이 있으면 (어셈블러가 있으면) 일을 시킬수 있다.
       

    • 왜 고급언어가 도입되었는가?
    • 위의 어셈블리어는 기계어를 단지 기호로 표현한것일 뿐이다. 그러므로 어떤 CPU가 다른 명령어나 구조로 구현되었다면 마찬가지로 어셈블리어도 다른 기호로 표현해야만 한다. 예를 들어 인텔에서 만든 CPU 와 모토롤라에서 만든 CPU 는 유사한 작업을 시키는것도 다르게 기계어를 기술해야 하며 이때 사용하는 레지스터도 다르다. 그러므로 어셈블리어는 모든 CPU 별로 존재해야만 한다.

      이는 여러개의 CPU에 일을 시키기 위해서는 해당 CPU 마다의 어셈블리어를 잘 알아야 한다는것이다. 또한 하나의 CPU에서 구현한 어셈블리어는 다른 CPU에서는 동작될수 없음으로 다시 프로그램 해야한다는것이다. 이런 단점을 극복하고자 명령어 수준에서 시킬 일을 기술하지 않고 동작 수준에서 일을 시키게 하는 고급언어가 등장하였다.

      고급언어에서는 특정 CPU에 한정된 명령어를 사용하라든가 이때 어떤 레지스터를 사용하라든가를 기술하지 않고 보다 상위레벨에서 기술함으로서 어떤 CPU의 기계어로도 번역이 가능하게된다. 아래의 예를 보면 인텔 8086에서와 모토롤라 68000 에서 어떻게 어셈블리어가 틀려지는지 볼수있다. 먼저 MOV 와 MOVE 는 비슷한 동작을 하나 인텔 8086에서는 두번째 피연산자가 첫번째 피연산자로 로 지적된 레지스터 DX로 move 한다. 이에반해 모토롤라 68000에서는 첫번째 피연산자가 두번째 피연산자로 지적된 레지스터 D0로 move 한다. 여기서 방향성은 기술시의 차이점이라고 무시할수도 있겠으나 레지스터 셋이 다름으로 분명히 기술상의 차이점을 발견할수 있다. 또한 8086에서는 구현된 명령이나 68000에서는 구현안된 명령어도 있을수 있다. 결국 두개의 어셈블리어는 상호 호환될수 없다. 그러나, 고급언어인 C에서는 어떤 명령어를 사용하라든가 어떤 레지스터를 사용하라는 구체적인기술없이 단지 A라는 변수 값과 B라는 변수값을 더해서 SUM 이라는 변수갑에 넣어라 라는 동작적인 기술만 되어있음으로 다른 CPU 상에서도 호환될수 있다.  
       
      인텔 8086
      모토롤라 68000
      C 언어
      MOV   DX, A   
      ADD    DX, B   
      MOV   SUM, DX
      MOVE.W   A, D0   
      ADD.W     B ,D0   
      MOVE.W   D0, SUM
      SUM = A + B;
       

      어셈블리어에서와 마찬가지로 특정 CPU 가 고급언어를 실행하려면 기계어로 바뀌어야만 한다. 어셈블리어에서 어셈블리어를 기계어로 바꾸어주는 어셈블러라는 프로그램이 있듯이 고급언어에서는 해당 고급언어를 기계어로 바꾸어주는 컴파일러라는 프로그램이 필요하다. 보통 컴파일러에서는 옵션을 설정함으로서 고급언어를 어셈블리어로 변환하는것도 가능하다. 그러므로, 고급언어가 어떻게 어셈블리어로 변환되는지 알고싶은 학생은 이를 실행하여 컴파일러가 변환한 어셈블리어를 한번 살펴보는 것도 도움이된다.

      Turbo-C 컴파일러에서는 tcc -S test.c 하면 test.asm 이라는 변환된 어셈블리어 화일을 만든다.