자바스크립트

[번역] 어셈블리 집중 코스

이 글은 모질라 Hacks의 웹어셈블리 시리즈 중 세 번째 글인 A crash course in assembly의 번역글이다. 전 시리즈에 걸쳐 웹어셈블리 뿐만 아니라 JIT나 어셈블리 등에 대해서도 체계적으로 잘 설명하고 있고, 카툰까지 곁들여서 이해하기도 쉽다.

총 6부로 되어 있으며, 원작자의 허가를 얻어 전체 시리즈를 모두 번역했으니 처음부터 차례대로 모두 읽어보길 권한다.

  1. 카툰으로 소개하는 웹어셈블리
  2. 저스트-인-타임(JIT) 컴파일러 집중 코스
  3. 어셈블리 집중 코스 (현재글)
  4. 웹어셈블리 모듈의 생성과 동작
  5. 웹어셈블리는 왜 빠를까?
  6. 웹어셈블리의 현재 위치와 미래

 

웹어셈블리가 어떻게 작동하는지를 이해하기 위해서는, 어셈블리가 무엇이고 컴파일러가 어떻게 그것을 생성해내는지를 이해하는 것이 도움이 될 것이다.

JIT에 대해 설명한 글에서 나는 기계와 의사소통을 하는 것이 마치 외계인과 의사소통을 하는 것과 비슷하다고 설명했다.

03-01-alien03-500x286.png

이제 나는 그 외계인의 뇌가 어떻게 작동하는지를 – 즉, 기계의 뇌가 들어오는 정보를 해석하고 이해하는지 – 를 살펴보도록 하겠다.

기계의 뇌에는 생각을 위해 존재하는 부분이 있으며 더하기, 빼기 혹은 논리 연산 등을 수행한다. 또한 그와 가까운 곳에 단기 기억을 제공하는 부분과 장기 기억을 제공하는 부분도 있다.

이들 각각의 부분은 이름을 갖는다.

  • 생각을 담당하는 부분은 산술 논리 장치 (ALU : Arithmetic Logic Unit)이다.
  • 단기 기억은 레지스터에 의해 제공된다.
  • 장기 기억은 랜덤 억세스 메모리 (RAM : Random Access Memory)이다.

03-02-computer_architecture09-500x302.png

기계 코드 내에서의 문장들은 명령(instruction)이라고 불린다.

이러한 명령들 중 하나가 뇌 속으로 들어오면 어떤 일이 벌어질까? 그 명령은 각기 다른 의미를 가진 부분으로 나누어진다.

이 명령이 나누어지는 방식은 뇌의 회로에 의해 특정지어진다.

예를 들어 이런 식으로 구성된 회로를 갖는 뇌는 항상 처음 여섯 비트를 ALU 로 전송할 것이다. ALU는 1과 0의 위치를 기반으로, 두 값을 함께 더해야 한다는 것을 알아낸다.

이 조각은 “opcode” 혹은 연산 코드(operation code)라고 불리는데, 왜냐하면 이것이 ALU에게 어떤 연산을 수행할지를 말해주기 때문이다.

03-03-computer_architecture12-500x354.png

그 후에 뇌는 덧셈을 할 두 개의 수가 무엇인지 알아내기 위해 세 개의 비트로 이루어진 다음 두 조각을 읽어온다. 이들은 레지스터의 주소일 것이다.

03-04-computer_architecture17-500x352.png

기계 코드 위에 있는 주석을 잘 살펴보자. 이를 통해 우리 인간이 기계 코드를 좀더 쉽게 이해할 수 있는데, 이것이 바로 어셈블리이다. 상징적(symbolic) 기계 코드라고도 불린다. 이것이 인간이 기계의 코드를 이해할 수 있는 방법이다.

여기서 어셈블리와 기계 코드 사이에는 꽤 직접적인 관계가 있는 것을 볼 수 있을 것이다. 이 때문에 여러 종류의 기계 아키텍쳐에 맞는 각기 다른 어셈블리가 존재한다. 다른 아키텍쳐의 머신에게는 그 머신에게만 통용되는 별도의 어셈블리가 필요하다.

즉, 번역의 목표 대상이 하나만 있는 것이 아니다. 단순히 하나의 기계 코드가 있는 것이 아니다. 아주 다양한 종류의 기계 코드가 있다. 사람들이 각자 다른 언어로 이야기하듯이, 기계들도 각자 다른 언어로 이야기한다.

인간의 언어를 외계인에게 번역한다면, 아마 영어나 러시아어 혹은 중국어를 외계인 언어 A 혹은 외계인 언어 B로 번역하게 될 것이다. 프로그래밍 용어로 말하자면 C, C++, Rust 등을 x86 이나 ARM으로 번역하는 것이 될 것이다.

이들 상위 레벨 프로그래밍 언어들 중의 하나를 어셈블리 언어들 중 하나로 번역한다고 해 보자. 가능한 한 가지 방법은 각 언어에서 각 어셈블리로 번역할 수 있는 각기 다른 모든 번역기를 만드는 것이다.

03-05-langs05-500x308.png

이 방법은 꽤나 비효율적이다. 이를 해결하기 위해 대부분의 컴파일러는 둘 사이에 최소한 하나의 레이어를 둔다. 컴파일러는 상위 레벨 프로그래밍 언어를 읽어서, 너무 상위 레벨도 아니면서 기계 코드의 레벨에서 동작하지도 않는 무언가로 번역한다. 이것을 중간 표현 형식 (IR: Intermediate representation) 이라고 한다.

03-06-langs06-500x317.png

이 말은 곧 컴파일러가 이들 상위 레벨 언어들 중 어떤 것이든 읽어서 단일 IR 언어로 번역할 수 있다는 의미이다. 여기서부터 컴파일러의 다른 부분이 이 IR을 읽어서 특정 대상의 아키텍쳐에 맞게 컴파일할 수 있게 된다.

컴파일러의 프론트엔드는 상위 레벨 프로그래밍 언어를 IR로 번역한다. 컴파일러의 백엔드는 IR을 대상 아키텍쳐의 어셈블리 코드로 번역한다.

03-07-langs09-500x306.png

결론

지금까지 어셈블리가 무엇이고, 컴파일러가 상위 레벨 프로그래밍 언어를 어떻게 어셈블리로 번역하는지를 살펴보았다. 다음 글에서는 웹어셈블리가 여기에 어떻게 적용되는지를 살펴보겠다.

Lin Clark 에 대해

Lin은 모질라 개발자 관계 팀의 엔지니어이다. 그녀는 자바스크립트, 웹어셈블리, Rust, Servo 등을 끄적거리며, 코드 카툰을 그린다.

코드카툰 : http://code-cartoons.com/
트위터 : @linclark

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s