저번 포스트에서는 번역기의 종류에 대하여 알아보았습니다. 이번 포스트에서는 어셈블러를 설명하고 후에 세세한 설명과 예를 통해 풀어나갈 예정입니다.
어셈블러는 어셈블리어로 작성된 소스 프로그램을 그에 대응하는 기계어로 번역된 목적 프로그램으로 변환해주는 번역기이고, 어셈블리어는 기계어를 사람이 좀 더 이해하기 쉽도록 기호화한 것입니다. 어셈블리 명령어(instruction)는 목적 기계에 따라 다르게 표현되는데 [아래의 그림]에서 예제를 다루어 보았습니다.
※ 어셈블리 명령어의 예
LOAD R1, a 코드는 변수 a에 있는 값을 레지스터 R1에 적재하라는 것이고, ADD R1, #2 코드는 레지스터 R1에 있는 값과 상수 2를 더하여 레지스터 R1에 저장하라는 것이며, 마지막으로는 STORE b, R1 코드는 레지스터 R1에 저장되어 있는 값을 변수 b에 저장하라는 것이다. 이렇게 하면 치환문 b = a + 2를 계산하는 코드입니다.
어셈블러를 구현하는 방법은 여러 가지가 있는데, 그중에서 가장 많이 사용되면서 가장 간단한 형태는 2-패스(two pass) 어셈블러입니다. 여기서 하나의 패스란 하나의 입력 파일을 단 한 번만 읽는 것으로 구성되는 단위를 말한다. 즉 2-패스 어셈블러는 2개의 패스로 구성됩니다.
첫 번째 패스에서는 메모리를 표시하는 모든 식별자를 찾아내고 그 식별자들을 기호표(symbol table)에 저장합니다. 예를 들어 [어셈블리 명령어의 예]의 코드를 읽으면 [아래의 그림, 예제 2]와 같은 항목을 포함하는 기호표가 만들어집니다. [예제 2]에서는 하나의 단어(word)가 4바이트로 구성되고 각 식별자의 주소가 0바이트부터 시작한다고 가정했습니다.
두 번째 예제에서는 각 연산 코드를 기계어에서 수행될 수 있는 비트의 표현으로 나타냅니다. 예제 2의 어셈블리 명령어에 대한 가상적인 기계어는 아래의 그림과 같습니다.
예제 3에서 첫 번째 4비트는 명령어로 0001은 LOAD, 0011은 ADD, 0010은 STORE을 나타냅니다. LOAD는 메모리에서 레지스터로 자료를 옮기고, STORE는 레지스터에서 메모리로 자료를 옮깁니다. 그다음 2비트는 레지스터를 표시하는 것으로 여기서 01은 레지스터 1을 의미합니다.
이어서 그다음 2비트는 태그를 나타내는데, 00은 다음의 8비트가 메모리 주소를 가리키는 일반적인 주소 방식(Ordinary Address Mode= 명령의 주소부가 피연산자가 저장되어 있는 기억장치의 주소를 지시) 일 때, 10은 다음의 8비트가 피연산자인 직접 번지 지정 방식(Immediate address mode= 주소의 값 자체가 피연산자)일 때 사용됩니다. *는 각각의 피연산자가 재배치(relocatable) 가능 기계어에서 재배치 비트임을 나타내는 것입니다.
※ 오늘은 '어셈블러'에 대하여 알아보았습니다.
이 포스트는 학부에서 제공하는 기본적인 강의와 책들을 토대로 알기 쉽게 내용을 작성하였습니다. 하지만 계속 더 유익하고 논문 및 전문 서적을 읽어가며 더 추가돼야 할 내용이 있으면 컴파일러 포스트와 콘텐츠들을 계속 고도화하는 방식으로 진행하려고 합니다.
'컴퓨터공학 > 컴파일러' 카테고리의 다른 글
[컴파일러] 프리 프로세서 (0) | 2019.09.29 |
---|---|
[컴파일러] 번역기의 종류 (0) | 2019.09.29 |
[컴파일러] 컴파일러는 왜 필요할까? (0) | 2019.09.27 |