8비트 임베디드 시스템을 위한 타겟 재설정 가능 컴파일러에 ... ·...

44
工學碩士學位論文 8 비트 임베디드 시스템을 위한 타겟 재설정 가능 컴파일러에 관한 연구 A Study on Retargetable Compiler for 8bit Embedded Systems 2004 年 2 月 仁荷大學校 大學院 電子計算工學科

Transcript of 8비트 임베디드 시스템을 위한 타겟 재설정 가능 컴파일러에 ... ·...

  • 工學碩士學位論文

    8 비트 임베디드 시스템을 위한

    타겟 재설정 가능 컴파일러에 관한 연구

    A Study on Retargetable Compiler

    for 8bit Embedded Systems

    2004 年 2 月

    仁荷大學校 大學院

    電子計算工學科

    洪 一 敬

  • 工學碩士學位論文

    8 비트 임베디드 시스템을 위한

    타겟 재설정 가능 컴파일러에 관한 연구

    A Study on Retargetable Compiler

    for 8bit Embedded Systems

    2004 年 2 月

    指導敎授 金 基 昌

    이 論文을 碩士學位論文으로 提出함

    仁荷大學校 大學院

    電子計算工學科

    洪 一 敬

  • 이 論文을 洪一敬의 碩士學位論文으로 認定함.

    2004 年 2 月 日

    主審 印

    副審 印

    委員 印

  • i

    요 약

    임베디드 시스템의 기능이 복잡해지면서 소프트웨어 또한 복잡해지고 있다.

    따라서 소프트웨어의 재사용은 임베디드 시스템에서 중요한 관점이 되었다.

    그러나 많은 임베디드 프로그램은 컴파일러와 프로세서 아키텍처에 매우

    의존성이 강해서 다양한 아키텍처에서 재사용하기가 어렵다.

    또한 하드웨어 개발 주기가 짧아지면서 이를 지원하는 컴파일러 기술도

    중요성도 더불어 증대되었다. 이런 제한된 재사용 성을 극복하기 위해

    하드웨어 아키텍처 독립적인 부분을 재사용하고 하드웨어 아키텍처에 대한

    필요한 정보들을 기술하여 전체 컴파일러의 재 작성 없이 짧은 시간 안에

    최적의 성능을 낼 수 있는 타겟 재설정 가능 컴파일러(Retargetable

    Compiler)의 개발이 이슈가 되었다.

    그러나 기존의 타겟 재설정 가능 컴파일러는 32비트 범용 프로세서를

    기준으로 제작되었기 때문에 8비트 프로세서를 사용하는 임베디드 시스템의

    경우 C언어의 정수형 자료형 사이즈가 1바이트로 처리되는 경우와 ANSI

    C표준에서 지원하지 않는 키워드 사용으로 인해 자동으로 타겟 어셈블리

    코드가 생산되지 못하는 문제점이 있다.

    따라서 8비트 임베디드 시스템을 지원할 수 있도록 적절한 컴파일러의

    변경이 필요하다.

    이에 본 논문에서는 첫째, 현재 연구중인 타겟 재설정 가능 컴파일러를

    분석하여 자료형 사이즈의 문제가 되는 부분들의 소스 코드를 수정, 추가한다.

    둘째, ANSI C표준에서 지원하지 않는 키워드를 처리하기 위해 소스 코드를

    추가한다. 마지막으로 타겟 어셈블리 코드가 생산되기 위해 필요한 Machine

    Description 파일을 작성하여 8비트 임베디드 시스템에서 타겟 재설정이

    가능하고 자동으로 타겟 어셈블리 코드가 생산되도록 타겟 재설정 가능

    컴파일러를 개선하는 방안에 대해 제안한다.

  • ii

    Abstract

    Since embedded software is becoming more and more complex, software

    reuse is an important issue in processor-based embedded systems.

    However, many embedded programs can not be reused on various kinds of

    architectures because the correctness of programs strongly depends on

    both compilers and processor architectures. As the development cycles

    are getting shorter every days, the speed of compiler development has

    become an important issue. The use of retargetable compiler that reuses

    hardware independent parts of existing compilers can be an effective

    solution for speeding up compiler development cycles by improving

    software reusability. However, today’s retargetable compilers that are

    designed for 32-bit general purpose micro-processors are not able to

    generate target code for industrial embedded systems that are running on

    8-bit processors. Since 8-bit processors for industrial purposes have

    features like 1-byte integer variables, or some keywords that are not ANSI

    compliant, modifications are needed to make those compilers support

    industrial embedded systems. Therefore, retargetable compilers are

    required to be modified to support 8-bit embedded systems. The method

    of improving retargetable compilers, which is proposed in this paper,

    covers following topics: how to make target compilers handle data types

    that are unique for 8-bit systems, how to extend syntax of ansi C to handle

    non-ansi keywords of 8-bit embedded systems, and how to describe

    machine descriptions which enable retargeting and generating target

    assembly codes for 8-bit embedded systems, automatically.

  • iii

    목 차

    제 1 장 서 론 ..............................................................................1

    제 2 장 관련 연구 .......................................................................3

    2.1 타겟 재설정 가능 컴파일러(Retargetable Compiler)..............................3

    2.2 lcc 컴파일러.............................................................................................5

    2.3 8비트 임베디드 시스템 적용 시 문제점.................................................14

    제 3 장 8비트 임베디드 시스템의 타겟 재설정 가능 컴파일러 18

    3.1 배열 요소의 사이즈 문제 해결 ..............................................................18

    3.2 키워드 처리 문제 해결 ..........................................................................21

    3.3 Code Generator 구조 ............................................................................24

    제 4 장 실험 및 실험 결과........................................................27

    4.1 타겟 어셈블리 코드 출력 및 확인 실험 ................................................28

    4.2 실험 결과 ...............................................................................................32

    제 5 장 결론..............................................................................34

    참고 문헌....................................................................................35

  • 1

    제 1 장 서 론

    임베디드 시스템은 컴퓨터의 하드웨어와 소프트웨어, 기타 추가적인 기계

    장치 등으로 구성되어 특정 기능을 수행하도록 설계된 시스템이다[1]. 이러한

    임베디드 시스템은 마이크로프로세서가 개발된 이후로 대부분의 전자제품과

    첨단 제어 시스템에 이용되어 왔으며 현재에 이르러는 정보가전기기를

    중심으로 그 수가 급속하게 증가하고 있는 추세이다.

    최근 임베디드 시스템의 기능이 복잡해지면서 소프트웨어 또한 복잡해지고

    있다. 따라서 소프트웨어의 재사용은 임베디드 시스템에서 중요한 관점이

    되었다. 그러나 많은 임베디드 프로그램은 컴파일러와 프로세서 아키텍처에

    매우 의존성이 강해서 다양한 아키텍처에서 재사용 하기가 어렵다[6]. 또한

    새로운 아키텍처를 가지는 제품의 개발 주기가 점차 짧아지는 추세에 있으며

    이를 지원할 수 있는 컴파일러 기술의 중요성도 함께 증대되고 있지만

    전통적인 컴파일러는 개발 프로세스가 길기 때문에 새로운 하드웨어의 개발

    속도를 따라 대응하는데 큰 어려움이 있다. 이러한 문제점을 해결하고자

    하드웨어 아키텍처 독립적인 부분을 재사용하고 하드웨어 아키텍처에 대한

    필요한 정보들을 기술하여 전체 컴파일러의 재 작성 없이 짧은 시간 안에

    최적의 성능을 낼 수 있는 타겟 재설정 가능 컴파일러(Retargetable

    Compiler)의 개발이 이슈가 되고 있다.

    그러나 대부분의 타겟 재설정 가능 컴파일러는 32비트 범용 프로세서를

    기준으로 설계되어 있기 때문에 8비트 프로세서를 사용하는 산업용 임베디드

    시스템의 경우 C언어의 정수형 자료형 사이즈가 1바이트로 처리되는 경우와

    ANSI C표준에서 지원하지 않는 키워드 사용으로 인해 자동으로 타겟

  • 2

    어셈블리 코드가 생산되지 못하는 문제점이 있다.

    본 연구가 제안된 동기는 국내에서 임베디드 시스템용 8비트 프로세서를

    제작하는 업체의 경우 프로세서를 지원하기 위한 컴파일러를 국내에서

    제작하기 어려워 해외 업체에 의뢰하여 제작하는데 기능 추가로 인해

    하드웨어 아키텍처가 수정된 경우 전체 컴파일러의 제작 비용을 다시

    지불해야 하는 문제점이 있기 때문에 현재 국내외에서 연구중인 타겟 재설정

    가능 컴파일러의 임베디드 시스템 적용 가능성과 문제점 그리고 해결책을

    연구하기 위함이다.

    본 논문에서는 산업용 제어 시스템에서 많이 사용되고 있는 임베디드용

    8비트 마이크로 컨트롤러인 ATMEL사의 AT90S8515와 ST사의 ST5

    408모델을 대상으로 리타겟팅이 가능하도록 lcc 컴파일러를 개선하는 방안에

    대해 제안한다.

    본 논문의 구성은 다음과 같다. 제2장에서는 관련연구들을 소개한다. 먼저

    타겟 재설정 가능 컴파일러에 대해 소개하고 lcc 컴파일러의 구조와 컴파일

    과정을 소개하고, 임베디드 시스템에 적용 시 그에 대한 문제점을 제시한다.

    제3장에서는 본 논문에서 제안하는 임베디드 시스템의 타겟 어셈블리 코드가

    자동으로 출력되도록 lcc 컴파일러를 이용하여 적용하는 과정을 설명한다.

    제4장에서는 실험 및 실험 결과를 보이고, 마지막으로 제5장에서는 결론 및

    향후 연구방향에 대해 설명하고 끝을 맺는다.

  • 3

    제 2 장 관련 연구

    2.1 타겟 재설정 가능 컴파일러(Retargetable Compiler)

    일반적인 컴파일러의 경우 General-Purpose Processor와 같이 하나의

    프로세서를 타겟으로 하기 때문에 다른 프로세서들에 대해서는 재사용하기

    힘들다. 그러나 타겟 재설정 가능 컴파일러의 경우는 프로세서 아키텍처가

    변화하여도 전체적인 컴파일러의 재 작성 없이 프로세서 아키텍처에 대한

    필요한 정보들을 기술하는 Machine Description을 작성함으로써 C언어와

    같은 고급 언어로 작성된 프로그램을 재사용하여 개발 프로세스를 단축시킬

    수 있다[5].

    [그림 2-1] 타겟 재설정 가능 컴파일러의 기본 개념

    [그림 2-1]은 타겟 재설정 가능 컴파일러의 기본 개념을 나타낸 그림이다.

    C언어와 같은 고급 언어의 소스 코드를 입력 받으면 대상이 되는 프로세서의

  • 4

    Machine Description을 읽어 들여 최종적으로 타겟 프로세서의 어셈블리

    코드를 출력하게 된다.

    타겟 재설정 가능 컴파일러의 궁극적인 사용 목적은 타겟 프로세서 종속적인

    부분만 수정을 가하여 타겟 프로세서와는 독립적인 컴파일러 일부분을

    재사용하여 하드웨어 아키텍처의 빠른 변화를 대응하기 위함이다.

    타겟 재설정 가능 컴파일러는 크게 전반부, 후반부, Machine Description의

    3부분으로 나눌 수 있다. 전반부(Front End)는 중간 표현(Intermediate

    Representation)까지의 과정으로 타겟 프로세서 아키텍처와는 연관성을

    가지지 않는 독립적인 부분에 해당된다. 후반부(Back End)는 타겟 프로세서의

    어셈블리 출력 코드와 연관된 부분으로 타겟 프로세서의 아키텍처와 종속적인

    부분이다. Machine Description부분은 후반부와 연관성을 가지는데 그 이유는

    리타겟팅하기 위한 타겟 프로세서의 specification 정보가 Machine

    Description으로 표현이 되고, 타겟 재설정 가능 컴파일러가 Machine

    Description 을 처리하여 후반부를 구성하기 때문이다. 일반적인 컴파일러는

    특정 프로세서에 고정이 되어 있기 때문에 단일의 Machine Description이

    바로 후반부로 표현이 되었다는 점에서 타겟 재설정 가능 컴파일러와는

    다르다고 할 수 있다.

  • 5

    [그림 2-2] lcc 컴파일러의 컴파일 처리 과정

    [그림 2-2]는 타겟 재설정 가능 컴파일러중 하나인 lcc 컴파일러의 컴파일

    과정을 보여주고 있다. [그림 2-2]의 lcc 컴파일러의 경우는 Code Generator

    로 표현되는 Machine Description을 Code-Generator Generator가 처리하여

    후반부를 구성한 후 타겟 프로세서의 어셈블리 코드를 출력한다[9].

    2.2 lcc 컴파일러

    lcc 컴파일러는 현재 Princeton 대학에서 연구중인 타겟 재설정 가능

    컴파일러로 오픈 소스 프로젝트로 진행하고 있으며 크기가 작고 ANSI C를

    지원하며 대부분의 32비트 범용 프로세서에 대해 리타겟팅을 지원하고 있다.

    lcc 컴파일러는 다른 타겟 재설정 가능 컴파일러에 비하여 크기가 작고

    소스가 공개되어 있기 때문에 분석이 용이하여 본 논문의 실험을 위한 타겟

    재설정 가능 컴파일러로 선정하였다.

    2.2.1 lcc 컴파일러 구조

    lcc 컴파일러의 코드 구성은 [표 2-1]과 같다. [표 2-1]은 lcc 컴파일러의

  • 6

    전반부에 해당하는 코드와 해당 타겟 프로세서의 Machine Description에

    해당하는 Code Generator를 보여주고 있다. 이 Code Generator 파일은 각

    타겟 프로세서의 리타겟팅을 위해 손으로 작성한 파일로 타겟 프로세서와

    타겟 플랫폼(platform)의 조합으로 구성되어 있다. 또한 Code Generator를

    처리하기 위한 Code-Generator Generator인 lburg부분이 추가된다.

    [표 2-1] lcc 코드 구성과 기능

  • 7

    [그림 2-3] 한 개의 전반부와 다수의 후반부로 구성된 lcc의 모놀리식 설계

    [그림 2-3]은 Code Generator가 적용되어 구성된 lcc 컴파일러를 표현한

    것으로 한 개의 전반부와 타겟 프로세서와 플랫폼의 짝을 이루는 타겟의

    개수만큼의 후반부가 하나의 전체적인 컴파일러를 이루고 있다. lcc

    컴파일러의 전반부는 C언어로 작성된 소스를 읽어 형태소 분석과 구문 분석의

    과정을 거쳐 대그(DAG: Directed Acyclic Graph)형태의 중간 표현을

    생성한다. Code Generator를 처리하여 생성된 후반부는 전반부에서 생성된

    중간 표현에 대한 처리 과정을 통해 최종 타겟 어셈블리 코드를 출력한다.

    2.2.2 IR(Interface Record)

    IR(Interface Record)는 lcc 컴파일러에서 각 타겟의 특성과 관련된 데이터

    정보를 담고 있는 구조체이다. IR은 크게 type metrics, interface flags,

    interface function에 대한 포인터, 후반부에서 사용하기 위해 타겟과 연관된

    정보를 저장하고 있는 확장 필드 4부분으로 구성되어 있다.

  • 8

    [그림 2-4] type metrics 구조체

    [그림 2-4]는 IR에 선언된 각 원시 타입(primitive type)의 size와

    alignment를 보여주고 있다. outofline 변수는 관련된 타입이 상수인 경우의

    배치 문제를 나타내는 플래그(flag)이다. outofline값이 1일 경우 상수는

    대그안에서 표현될 수 없고 임의의 정적 변수들이 위치하는 공간에 저장한 후

    필요할 때 값을 fetch하는 방식으로 값에 접근할 수 있다. 보통 후반부는

    값들이 명령어의 즉시 피 연산자(immediate operands)로써 표현이 가능한

    경우에만 outofline 플래그를 0으로 세트 시킨다.

    1 Typedef struct interface {

    2 Metrics charmetric;

    3 Metrics shortmetric;

    4 Metrics intmetric;

    5 Metrics longmetric;

    6 Metrics longlongmetric;

    7 Metrics floatmetric;

    8 Metrics doublemetric;

    9 Metrics ptrmetric;

    10 Metrics structmetric;

    11 unsigned little_endian:1;

    12 unsigned mulops_calls:1;

    13 unsigned wants_callb:1;

    14 unsigned left_to_right:1;

    15 unsigned wants_dag:1;

    16 unsigned unsigned_char:1;

    17 void (*address)(Symbol, Symbol, long);

    18 void (*blockbeg)(Env *);

  • 9

    19 void (*blockend)(Env *);

    20 void (*defaddress)(Symbol);

    21 void (*defconst)(int, int, Value);

    22 void (*defstring)(int n, char *);

    23 void (*defsymbol)(Symbol);

    24 void (*emit)(Node);

    25 void (*export)(Symbol);

    26 void (*function)(Symbol, Symbol[], Symbol[], int);

    27 Node (*gen)(Node);

    28 void (*global)(Symbol);

    29 void (*import)(Symbol);

    30 void (*local)(Symbol);

    31 void (*progbeg)(int, char *[]);

    32 void (*progend)(void);

    33 void (*segment)(int);

    34 void (*space)(int);

    35 void (*stabblock)(int, int, Symbol*);

    36 void (*stabend)(Coordinate *, Symbol, Coordinate **, Symbol *,

    Symbol *);

    37 void (*stabfend)(Symbol, int);

    38 void (*stabinit)(char *, int, char *[]);

    39 void (*stabline)(Coordinate *);

    40 void (*stabsym)(Symbol);

    41 void (*stabtype)(Symbol);

    42 Xinterface x;

    43 } Interface;

    [그림 2-5] Interface Record 구조체

    라인2~라인10은 기본 자료형을 정의한 type metrics이다. 각 타입의

    signed형과 unsigned형은 따로 구분하지 않고 같은 type metrics를 사용한다.

    라인11~라인16은 interface flags이다. 이 중 몇 개의 플래그를 살펴보면

    다음과 같다.

    unsigned little_endian:1;

    타겟이 little endian 방식이면 1로 설정하고, big endian 방식이면 0으로

  • 10

    설정한다.

    unsigned mulops_calls:1;

    타겟 프로세서가 하드웨어적으로 곱셈, 나눗셈, 나머지를 구현하고 있으면

    0으로 설정하고, 라이브러리 루틴을 사용하여 구현되면 1로 설정한다.

    unsigned left_to_right:1;

    후반부에서 인자(argument)의 처리를 왼쪽에서 오른쪽으로 하도록 지시하는

    플래그로써 1일 경우가 왼쪽에서 오른쪽으로 처리되고 0일 경우 오른쪽에서

    왼쪽으로 처리된다.

    unsigned unsigned_char:1;

    이 플래그는 front end 부분에 char형 타입이 signed 인지 unsigned 인지를

    알려주는 플래그로써 0일 경우 singed 타입이고 1일 경우 unsigned 타입이다.

    그 다음 살펴볼 부분은 Interface Function에 대한 부분이다. 이 부분은 크게

    4가지로 나누어 살펴 볼 수 있다. [표 2-2]는 Interface Function들의 종류와

    역할에 대해 보여주고 있다.

    Initialization부분은 초기화를 담당하는 부분이다. progbeg()함수는 옵션들을

    읽고 처리하는 함수로 후반부에서 이 옵션을 처리하도록 초기화 시키는

    역할을 한다. 그리고 progend()함수는 타겟 코드 출력과 연관된 부분들의

    초기화를 담당한다.

    Definition부분은 정의를 담당하는 부분이다. defsymbol()함수는 새로운

    심볼에 대한 정의가 이루어 지는 함수이고, export()함수는 현재 모듈에서

  • 11

    심볼이 정의가 되고, 외부 모듈에서 이 심볼을 참조할 경우에 출력 할 코드에

    대한 정의가 이루어 지고, import()함수는 외부 모듈에서 심볼이 정의 되고

    현재 모듈에서 참조할 경우에 출력 할 코드에 대한 정의가 이루어 지는

    함수이다. global()함수는 전역 변수를 정의하기 위한 코드를 출력하는

    함수이고, local()함수는 지역 변수 처리에 관련된 함수이다.

    [표 2-2] Interface Function의 기능과 해당 함수들

    기능 함수

    Initializationvoid (*progbeg)(int argc, char *argv[])void (*progend)(void)

    void (*defsymbol)(Symbol p)void (*export)(Symbol p)void (*import)(Symbol p)void (*global)(Symbol p)void (*local)(Symbol p)void (*address)(Symbol p, Symbol q, long n)void (*segment)(int seg)

    Definition

    void (*defaddress)(Symbol p)void (*defconst)(int suffix, int size, Value v)void (*defstring)(int n, char *s)void (*space)(int n)

    Constants

    void (*function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls)void (*emit)(Node)Node (*gen)(Node)void (*blockbeg)(Env *e)void (*blockend)(Env *e)

    Functions

    Constants부분은 상수 처리와 관련된 부분으로 defconst()함수는 상수의

    자료형 정의와 관련된 함수이고, defaddress()함수는 심볼들을 포함하는

    포인터 형 상수의 초기화와 관련된 함수이다. defstring()함수는 문자열의

  • 12

    길이만큼의 문자를 메모리에 기록하여 문자열을 정의해 주는 함수이고,

    space()함수는 인자 값으로 적힌 숫자만큼의 빈 공간을 할당해 주는 함수이다.

    Functions부분은 Code Generator에서 타겟 코드 출력에 사용되는

    함수들인데, 이 함수들은 전반부와 함께 연관되어 동작이 되는 함수들이다. 즉,

    이 함수들 중간 중간에 전반부의 함수들을 호출하면서 전반부에서 처리된

    일부 소스들이 이 함수들을 거치면서 바로 타겟 코드를 출력을 한다. 예를

    들면 C언어에서 전역 변수로 선언된 변수들에 대하여 어셈블리 코드를

    출력하는 부분이라고 할 수 있다.

    stab으로 시작되는 이름을 가지는 함수들은 디버깅 정보를 출력할 때 필요한

    함수들에 대한 포인터 함수들이다.

    마지막으로 x 필드는 후반부 처리를 위한 확장 부분으로 타겟 특성을

    처리하는데 추가적으로 정의한 함수들에 대하여 함수 포인터를 정의해 주는

    부분이다.

    Interface Record는 전반부와 후반부가 공통적으로 필요한 정보에 대한

    정의와 타겟의 특성을 처리하기 위한 후반부만이 필요한 부분에 대한 정의가

    이루어 지는 lcc 컴파일러의 가장 특징적인 부분이라 할 수 있다.

    2.2.3 Interface Binding

    Interface Binding은 출력 하고자 하는 타겟을 지정하여 해당 타겟의 IR이

    연결 되도록 한다. 해당 타겟에 대한 코드를 출력하기 위해서는 컴파일

    옵션에 –target=name을 추가해 주면 된다. 따라서 –target 뒤에 오는 name의

    이름을 가지는 IR에 연결된 함수들이 소스의 컴파일 과정에서 처리 된다.

  • 13

    [그림 2-6] Interface Record Binding

    [그림 2-6]은 옵션에 타겟 이름이 지정이 되면 각 타겟당 하나씩 존재하는

    IR에 컴파일 명령어에서 –target 옵션의 이름으로 지정된 타겟의 IR로

    바인딩이 일어나는 것을 보여주는 그림이다.

    [그림 2-7] Inerface Binding 구조체

    출력 가능한 타겟에 대하여 이름과 IR의 쌍으로 이루어진 바인딩 정보가

    [그림 2-7]에서 보여지는 구조체에 저장 되어 있다. 새로운 타겟에 대한

  • 14

    코드를 출력하기 위해서는 이 바인딩 구조체 형태로 binding[]에 새로운

    타겟에 대한 이름과 연결할 IR을 등록해 주어야 한다.

    2.3 8비트 임베디드 시스템 적용 시 문제점

    임베디드 시스템 중 산업용 제어 시스템의 임베디드 프로세서는 대부분이

    8비트 프로세서를 사용하고 있다. 그러나 현재 연구중인 타겟 재설정 가능

    컴파일러들의 경우 대부분이 32비트 프로세서를 중심으로 하고 있다.

    일반적인 타겟 재설정 가능 컴파일러는 Machine Description을 작성하여

    컴파일을 하면 자동으로 타겟 어셈블리 코드가 출력되도록 설계되어 있다.

    그러나 8비트 프로세서를 사용하는 임베디드 시스템을 타겟으로 지정하여

    Machine Description을 작성하여 타겟 어셈블리 코드를 출력시키면 자동으로

    타겟 어셈블리 코드가 출력되지 않는다. 그 이유를 크게 2가지로 요약해서

    설명할 수 있다.

    첫째는 8비트 프로세서를 위한 C언어의 자료형 사이즈가 32비트

    프로세서와는 다름으로 인해서 발생하는 문제이다. 즉, 8비트 프로세서에서

    C언어의 자료형 사이즈는 보통 정수형이 1바이트, long형이 2바이트, 실수

    형은 2바이트 또는 실수 형이 지원되지 않는 등의 경우들이 있다. 이런

    사이즈 문제로 가장 크게 영향을 받을 수 있는 부분이 배열 변수의 경우이다.

    일반적으로 산업용 임베디드 시스템에서는 제어하고자 하는 시스템들의

    변환되는 상태 값들을 배열 변수를 선언해서 저장하고 정보를 알려주는

    형식의 프로그래밍을 많이 하게 되는데 보통 배열 변수의 요소 사이즈를

    100~200정도의 크기로 선언하여 사용하고 최대 250까지도 선언해 사용하는

    경우가 빈번하다. 그러나 타겟 재설정 가능 컴파일러에서 배열 요소의

  • 15

    사이즈는 해당 타겟 자료형중 정수형 사이즈의 범위를 가지도록 설계되어

    있는 경우가 많이 있다. 즉, 정수형 사이즈가 1바이트인 경우 배열의 요소는

    1~127까지의 범위 내에서만 선언이 가능하다는 이야기다. 따라서 128이상의

    값을 선언해서 사용하고자 하는 경우 오버 플로우 에러를 내면서 타겟

    어셈블리 코드가 출력이 되지 않는 오류를 범하게 된다.

    [그림 2-8] 임베디드 시스템 리타겟팅 시 문제가 되는 코드

    [그림 2-8]의 코드는 임베디드 시스템 리타겟팅 시 문제가 발생할 수 있는

    코드로 lcc 컴파일러에서 컴파일 옵션만 주고 컴파일 했을 경우 문제가

    발생하지 않지만 임베디드 시스템으로 타겟을 지정하고 컴파일 했을 경우

    [그림 2-9]와 같은 에러 메시지를 출력하며 타겟 어셈블리 코드를 출력하지

    못한다.

    [그림 2-9] lcc 컴파일러에서 임베디드 시스템 리타겟팅 시 에러 메시지

  • 16

    둘째는 ANSI C에서 지원하지 않는 키워드의 사용문제로 인한 컴파일 에러

    문제이다. 임베디드 시스템에서는 프로그램이 거의 실시간과 가깝게 동작해야

    하는 경우가 많다. 그래서 프로세서를 제작하거나 Microcontroller를 제작할

    때 빠른 연산을 지원하기 위해서 특정 기능을 수행하는 레지스터를 추가하여

    제작하는 경우가 많이 있다. [그림 2-10]은 ST사의 Microcontroller의

    구조를 나타내는 그림이다. [그림 2-10]의 Microcontroller는 프로세서내의

    레지스터만 사용하여 연산을 하는 것이 아니라 추가된 레지스터에 변수를

    정의하고 연산하고 이러한 동작들을 명령어 셋(Instruction Set)에서

    지원하는데 C언어에서 역시 이러한 동작들을 지원하기 위해서 추가 키워드를

    사용하게 된다.

    [그림 2-10] ST사의 STMCU의 구조

    가령 예를 들면 creg라는 키워드는 Configuration Register를 가리키는

    키워드로 [그림 2-11]과 같이 사용할 수 있다.

  • 17

    [그림 2-11] ANSI C에서 사용하지 않는 키워드의 사용 예

    [그림 2-11]의 구문은 var1이라는 정수형 변수를 Configuration

    Register영역에 선언하겠다는 의미이다. 그러나 대부분의 타겟 재설정 가능

    컴파일러들은 ANSI C표준을 따르도록 설계가 되어 있기 때문에 [그림 2-

    11]과 같은 선언문을 만나면 문법 에러를 발생시키고 타겟 어셈블리 코드를

    출력하지 못한다.

  • 18

    제 3 장 8비트 임베디드 시스템의 타겟 재설정 가능 컴

    파일러

    배열 요소의 사이즈 문제가 임베디드 시스템의 1바이트 크기의 정수형일

    경우 발생한다. 키워드 문제는 컴파일러에서 사용하는 예약어로 처리하지

    못하고 사용자가 정의한 식별자로 잘못 인식하기 때문에 생기는 문법

    오류이기 때문에 본 논문에서는 사이즈를 변경해 처리하고 컴파일러가

    예약어로 처리할 수 있도록 키워드를 추가하여 Machine Description만

    작성해도 자동으로 타겟 어셈블리 코드가 출력되도록 컴파일러를 개선하는

    방안에 대해 제안한다.

    위의 제안을 만족하기 위해 우선 2.5절의 문제점과 관련된 타겟 재설정 가능

    컴파일러의 소스 분석이 필요하며, 타겟 어셈블리 코드를 출력시키기 위해

    Machine Description 작성이 필요하고, 올바른 타겟 어셈블리 코드가

    출력되었는지 확인하기 위해 기존의 타겟 프로세서를 지원하는 컴파일러와

    비교하여 정상적으로 타겟 어셈블리 코드가 출력되었는지 조사한다.

    3.1 배열 요소의 사이즈 문제 해결

    타겟 재설정 가능 컴파일러의 배열 요소는 정수형 자료형의 상수 값으로

    처리되어 있다. 32비트 프로세서의 경우 정수형 자료형은 4바이트이므로 배열

    요소의 사이즈 범위는 1~2,147,483,647이다. 그러나 1바이트 정수형

    자료형의 범위는 1~127까지로 제한이 된다.

    lcc 컴파일러의 소스 코드 중 decl.c 파일은 모든 선언문에 대해 처리하는

    모듈이 포함되어 있는 소스 파일이다. 이 소스 파일 내에 있는 dclr1()

    함수에는 배열의 요소로 지정된 상수(constants)에 대한 처리 구문이 들어

  • 19

    있는데 그 부분의 소스 코드는 [그림 3-1]과 같다.

    case '[' : t = gettok(); { int n = 0; if (kind[t] == ID) {

    n = intexpr(']', 1); if (n op == CNST+I || p->op == CNST+U)

    n = cast (p, inttype)->u.v.i;

    else

    error(“integer expression must be constant\n”);needconst--;

    return n;

    }

    [그림 3-2] intexpr() 함수의 소스 코드

    ‘[‘ 토큰(token) 다음에 오는 토큰이 사용자가 지정한 식별자인 경우

    intexpr() 함수를 호출하는데 이 함수의 역할은 정수형 상수 표현식을 해석해

    내는 함수로 []안에 선언된 토큰이 정수형 상수이거나 부호 없는 정수형인

  • 20

    경우 정수형 자료형으로 형 변환(casting)을 시키고 그렇지 않는 경우는

    정수형 상수 값을 입력해야 한다는 에러 메시지를 출력시키는 역할을 한다.

    intexpr() 함수의 소스 코드는 [그림 3-2]와 같다. 이 함수에서 배열 요소의

    자료형을 정수형 자료형으로 형 변환을 시키기 때문에 1바이트 사이즈의

    정수형 자료형의 경우 배열의 요소의 값이 127을 넘을 경우 오버 플로우의

    문제가 발생하게 되는 것이다. 따라서 [그림 3-1]코드에서 발생할 수 있는

    문제를 2바이트 사이즈의 long형으로 바꾸어 주면 오버 플로우 문제가 해결될

    수 있다. 임베디드 시스템에서 배열의 요소 사이즈가 250을 넘는 경우는 거의

    없기 때문에 1~32767범위의 사이즈를 갖도록 코드를 변경해 주면 된다.

    [그림 3-3]은 변경된 코드이다.

    case '[' : t = gettok(); { int n = 0; if (kind[t] == ID) {

    extern int emb;

    if (emb)

    n = longintexpr(']', 1);else

    n = intexpr(']', 1); if (n

  • 21

    long int longintexpr (int tok, int n) {

    tree p = constexpr(tok);

    needconst++;

    if (p->op == CNST+I || p->op == CNST+U)

    n = cast (p, longtype)->u.v.i;

    else

    error(“integer expression must be constant\n”);

    needconst--;

    return n;

    }

    [그림 3-4] 추가된 longintexpr()함수

    3.2 키워드 처리 문제 해결

    키워드 문제를 해결하기 위해 추가 키워드를 심볼로 등록해주어야 한다.

    그리고 컴파일러가 추가 키워드를 토큰(token)을 얻어 오는 과정에서 구분할

    수 있도록 형태소 분석 단계에 코드를 추가해 주어야 한다. 마지막으로

    extern이나 register처럼 선언 지정자(declaration specifier)처리를 해주면

    된다.

    3.2.1 추가 키워드의 심볼 등록

    token.h 헤더 파일은 lcc 컴파일러에서 토큰을 정의하는 파일이다. 이 파일에

    새롭게 추가되는 키워드를 [그림 3-5]와 같이 등록해 주어야 한다.

  • 22

    [그림 3-5] 키워드 등록 코드

    3.2.2 형태소 분석 과정 수정

    lex.c 파일의 gettok()함수는 소스 코드를 버퍼에서 읽어서 컴파일러에서

    정의한 예약어인 경우 구분해서 해당 예약어의 정수 값을 리턴 해주는

    함수이다. 이 gettok()함수 안에 추가된 키워드를 구분해내고 키워드에 할당된

    정수 값을 리턴해 주도록 코드를 추가해 주어야 한다.

  • 23

    [그림 3-6] 추가 키워드의 형태소 분석 과정 추가 코드

    [그림 3-6]은 추가된 키워드를 처리하기 위한 추가 코드의 일부분을

    보여주고 있다.

    3.2.3 선언 지정자 처리

    static Type specifier(int *sclass) {int cls, cons, sign, size, type, vol;Type ty = NULL;

    cls = vol = cons = sign = size = type = 0;if (sclass == NULL)

    cls = AUTO;for (;;) {

    int *p, tt = t;switch (t) {case AUTO:case REGISTER: if (level

  • 24

    extern변수나 register변수처럼 추가 키워드로 선언된 변수의 저장

    클래스(storage class)영역을 처리하여 선언 지정자 정보를 가지도록 처리해

    주어야 한다.

    3.3 Code Generator 구조

    Code Generator는 lcc 컴파일러에서 타겟 재설정 가능 컴파일러의

    Machine Description에 해당하는 부분으로 다음의 문법은 Code-Generator

    Generator인 lburg가 처리하기 위해서 Code Generator에 기술해야 할 기본

    형식이다.

    grammar:

    ‘%{’ configuration ‘%}’ { dcl } %% { rule } [ %% C code ]

    dcl:

    %start nonterm

    %term { term = integer }

    rule:

    nonterm : tree template [ C expression ]

    tree:

    term [ ‘(’ tree [ , tree ] ‘)’ ]

    nonterm

  • 25

    template:

    “ { any character except double quote } “

    %{, %} 그리고 %%는 라인에서 단독으로 사용이 되어야 한다. 그리고 dcl과

    rule은 꼭 표현해야 하고, configuration 부분은 C 코드로 표현된다.

    %start 지시자 다음에는 tree grammar의 root에 해당하는

    비단말(nonterminal) 기호의 이름이 표현된다. 만일 %start 지시자가 없는

    경우에는 첫 번째 rule에 의해 정의되는 비단말(nonterminal)기호가 start

    symbol이 된다.

    %term은 단말(terminal)기호를 선언한다. 이 단말 기호들은 트리상의

    연산자(operators)들로써 각 연산자는 유일한 정수형태의 opcode로 표현이

    되는데 이 정수형태의 opcode는 OP_LABEL(p)라는 매크로에 의해서

    생성되는 수이다. OP_LABEL(p) 매크로는 node p에 대한 정확한 opcode

    값을 리턴해 준다.

    문법의 제일 마지막에는 IR구조체에 정의되어 있는 Interface Function에

    대한 함수 정의가 이루어 진다.

    이렇게 만들어진 Code Generator는 md라는 확장자를 가지는 파일로 생성

    되는데 Code-Generator Generator인 lburg가 이 Code Generator를 읽어서

    C 파일을 생성하게 되고 lcc 컴파일러가 최종 컴파일 되면서 해당 타겟의

    C코드가 컴파일 된다.

    [그림 3-8]은 Code Generator의 일부분으로 초기화 하는 부분의 일부

    코드이다. 정수형 변수 emb 값은 초기화 과정에서 1로 셋팅이 되면서 수정된

  • 26

    코드들의 제어문에서 해당 코드들을 수행시키는 플래그 역할을 한다.

    [그림 3-8] Code Generator중 초기화 부분의 코드

  • 27

    제 4 장 실험 및 실험 결과

    본 장에서는 본 논문에서 제안한 3장의 임베디드 시스템을 위한 타겟 재설정

    가능 컴파일러를 구현하여 어셈블리 코드가 정상적으로 출력이 되는지

    확인하고, 출력된 어셈블리 코드를 실험 타겟의 어셈블러를 이용하여

    어셈블이 정상적으로 이루어 지는지 확인한다. 그리고 lcc 컴파일러와 실험

    타겟의 어셈블러를 통해 생성된 목적코드의 사이즈를 실험 타겟이 지원되는

    다른 컴파일러로 생성된 목적코드의 사이즈와 비교한다.

    본 실험은 RedHat Linux 9.0에서 이루어 졌으며, 구현을 위해 타겟 재설정

    가능 컴파일러인 lcc 컴파일러를 사용하였고 최종 버전인 4.2 버전을

    사용하였다.

    선정된 타겟 프로세서는 8비트 RISC(Reduced Instruction Set Computer)

    타입의 ATMEL의 AT90S8515에서 사용하는 프로세서로 256개의 8비트

    사이즈의 레지스터를 가지고 있다. 이 프로세서는 몇 개의 특수 레지스터를

    추가하여 MCU(Micro-Controller Unit) 형태로 만들어 사용이 가능한

    프로세서이다. 용어 사용의 편의성을 위하여 앞으로는 ‘EMB 프로세서’라는

    용어를 사용하도록 하겠다.

    이 EMB 프로세서의 C언어에서의 자료형의 정의는 다음과 같다.

    정수형(int) 사이즈는 1바이트

    포인터 형(pointer) 사이즈는 2바이트

    long형 사이즈는 2바이트

    char형은 unsigned 타입

  • 28

    실수 형(float)타입은 지원하지 않음

    4바이트 사이즈의 정수형은 지원하지 않음

    4.1 타겟 어셈블리 코드 출력 및 확인 실험

    [실험 1] EMB 프로세서용 어셈블리 코드 출력

    본 실험은 lcc 컴파일러의 명령어 옵션에 EMB 프로세서를 타겟으로

    지정하여 어셈블리 코드를 출력하는 실험이다.

    [그림 4-1]은 실험을 위해 작성된 C 소스 코드이다.

  • 29

    [그림 4-1] 실험을 위한 코드

    [그림 4-1]의 소스 코드를 다음과 같은 명령어를 통하여 어셈블리 코드를

    출력하였다.

    ]$ lcc –target=emb –S sample1.c

    출력된 어셈블리 코드는 [그림 4-2]와 같다.

    .cseg

    _fun1:

    sbiw r28,1

    ldi r30,low(10)

    cp r0,r30

    brge _L_2

    mov r19,r0

    subi r19,low(-1*10)

    std Y+(-1+1),r19

    rjmp _L_3

    _L_2:

    std Y+(-1+1),r0

  • 30

    _L_3:

    ldd r6,Y+(-1+1)

    _L_1:

    adiw r28,1

    ret

    _main:

    st -Y,r23

    ldi r30,low(5)

    mov r0,r30

    rcall _fun1

    mov r19,r6

    sts _gia,r19

    ldi r30,low(11)

    mov r0,r30

    rcall _fun1

    mov r19,r6

    sts _gib,r19

    ldi r23,low(0)

    rjmp _L_8

    _L_5:

    mov r26,r23

    clr r27

    sbrc r26,7

    com r27

    subi r26,low(-1*_array1)

    sbci r27,high(-1*_array1)

    ldi r19,low(48)

    st X,r19

    _L_6:

    subi r23,low(-1*1)

    _L_8:

    mov r26,r23

    clr r27

    sbrc r26,7

    com r27

    ldi r18,low(130)

  • 31

    ldi r19,high(130)

    cp r26,r18

    cpc r27,r19

    brlt _L_5

    clr r6

    _L_4:

    ld r23,Y+

    ret

    .dseg

    _array1:

    .byte 130

    _gib:

    .byte 1

    _gia:

    .byte 1

    [그림 4-2] 출력된 어셈블리 코드

    [그림 4-2]와 같이 출력된 어셈블리 코드가 오류가 없는지를 확인하기

    위해서 EMB 프로세서를 제조한 회사의 어셈블러를 통하여 어셈블을 해

    보았다.

    [그림 4-3] 에러가 발생하지 않은 어셈블 결과

    [그림 4-3]은 [그림 4-2]의 어셈블리 코드를 어셈블한 결과로 에러가

    발생하지 않았음을 알 수 있다.

  • 32

    4.2 실험 결과

    [실험 결과 1]

    lcc 컴파일러를 수정하여 타겟 어셈블리 코드를 출력한 결과 배열 변수의

    요소 사이즈가 130으로 127을 초과하였지만 이전에 발생하였던 오버 플로우

    오류를 발생시키지 않고 어셈블리 코드가 정상적으로 출력되었음을

    확인하였다. 또한 제조사의 어셈블러를 이용하여 어셈블한 결과 에러 없이

    어셈블이 완료 되었음을 확인 할 수 있었다.

    [실험 결과 2]

    [표 4-1]은 [그림 4-1]의 소스 코드를 기본 골격으로 코드를 추가하여 lcc

    컴파일러에서 출력된 어셈블리 코드를 어셈블하여 얻어진 목적 코드와 타겟

    프로세서를 지원하는 다른 컴파일러에서 얻어진 목적 코드와의 사이즈를

    비교한 표이다.

    비교 결과 사이즈 문제가 중요한 임베디드 시스템에서 lcc 컴파일러를

    통해서 만들어진 어셈블리 코드를 어셈블하여 만들어진 목적 코드 사이즈는

    기존의 상용 제품과 비교 하였을 때 평균 약 50%정도 사이즈가 작게

    나왔음을 알 수 있다.

  • 33

    [표 4-1] lcc 컴파일러와 타사 컴파일러의 목적 코드 사이즈 비교

    단위 : byte

    CodeVision 컴파일러

    C코드 사이즈 사이즈

    최적화

    속도

    최적화

    변경된

    lcc

    컴파일러

    사이즈

    최적화

    대비

    속도

    최적화

    대비

    rDummy_read

    FromFile() 290 1,311 1,320 515

    약 61%

    감소

    약 61%

    감소

    uart1_tx_isr() 436 1,545 1,608 731 약 54%

    감소

    약 55%

    감소

    initUART3() 582 1,743 1,896 947 약 46%

    감소

    약 50%

    감소

    TIMER0_com

    pare() 728 1,941 2,184 1,163

    약 40%

    감소

    약 47%

    감소

  • 34

    제 5 장 결론

    컴파일러의 재사용성을 위해 하드웨어 아키텍처 독립적인 부분은 그대로

    사용하고 하드웨어 아키텍처 종속적인 부분만 Machine Description을

    작성해서 타겟 어셈블리 코드를 자동으로 출력할 수 있도록 설계한

    컴파일러가 타겟 재설정 가능 컴파일러이다. 그러나 기존의 타겟 재설정 가능

    컴파일러는 32비트 범용 프로세서 환경에 적합하도록 설계되어 8비트

    프로세서를 사용하는 임베디드 시스템 적용 시 C언어의 자료형 사이즈 문제와

    키워드 문제로 타겟 어셈블리 코드가 자동으로 출력되지 않는 문제점이 있다.

    본 논문에서는 8비트 임베디드 시스템에 대하여 Machine Description 작성

    시 타겟 어셈블리 코드를 자동으로 출력하지 못하는 문제점을 해결하기

    위하여 배열 요소의 사이즈가 1바이트 정수형 시스템에서 문제가 발생하지

    않도록 코드를 수정, 추가하였고 ANSI C에서 지원하지 못하는 키워드를

    인식할 수 있도록 키워드 관련 코드들을 추가 작성하여 컴파일러의 전체적인

    재 작성 없이 타겟 재설정 가능 컴파일러를 수정하여 재사용할 수 있음을

    확인하였다.

    또한 출력된 어셈블리 코드를 어셈블하여 사이즈를 비교하는 실험을 하였고,

    목적 코드의 사이즈가 중요하게 여겨지는 임베디드 시스템에서 기존의

    임베디드 시스템용 컴파일러와 비교했을 때 평균 약 2배 정도 좋은 성능

    결과를 확인 할 수 있었다.

  • 35

    참고 문헌

    [1] Michael Barr, Programming Embedded Systems in C and C++, O’Reilly,

    1999.

    [2] C. W. Fraser and D. R. Hanson, A Retargetable Compiler for C : Design

    and Implementation, Addison-Wesley, Menlo Park, CA, 1995.

    [3] Aho, A. V., R. Sethi, and J.D.Ullman. 1986. Compilers : Principles,

    Techniques, and Tools. Reading, MA : Addison Wesley.

    [4] C. W. Fraser and D. R. Hanson, A Retargetable Compiler for ANSI C,

    SIGPLAN Notices 26, 10(Oct. 1991), 29-43.

    [5] 백윤흥, 프로세서 아키텍처에 적응하는 최적화 컴파일러 개발 최종 연구

    보고서, 한국 과학 기술원 BK21 정보기술 사업단, 2001.

    [6] A. Inoue, H. Tomiyama, E. F. Nurprasetyo, H. Yasuura, A Programming

    Language for Processor Based Embedded Systems, 1998.

    [7] C. W. Fraser and D. R. Hanson, A Lean Retargetable C Compiler, New

    York University, 4/4/96.

    [9] D. R. Hanson, Early Experience with ASDL in lcc, National Compiler

    Infrastructure Tutorial, SIGPLAN’98 Conference on Programming

    Language Design and Implementation, Montreal, 6/19/98.

    [10] C. W. Fraser, D. R. Hanson, and T. A. Proebsting, Engineering a

    Simple, Efficient Code Generator Generator, ACM Letters on Programming

    Languages and Systems 1, 3(Sep. 1992), 213-226.

    [11] N. Ramsey and D. R. Hanson, A Retargetable Debugger, Proceedings

  • 36

    of the SIGPLAN’92 Conference on Programming Language Design and

    Implementation, SIGPLAN Notices 27, 7(July 1992). 22-31.

    [12] U. Erlingsson, M. Krishnamoorthy and T. V. Raman, Efficient

    Multiway Radix Search Trees, Information Processing Letters 60, 3(Nov.

    11, 1996), 115-120.

    [13] C. W. Fraser and D. R. Hanson, A Minimalist’s Retargetable C

    Compiler, University of Delaware, 4/28/95.

  • 37

    감사의 글

    어느 덧 열정으로 굳게 시작한 대학원 생활을 이제 마무리하게 되었습니다.

    그 동안 많은 일들을 겪으며 지금까지 지내왔던 시간들을 되돌아보며, 그

    무엇보다도 대학원 생활의 시작부터 논문이 통과되기까지 지혜를 허락하신

    하나님께 감사 드립니다. 또한 너무나도 부족한 저를 끝까지 지도해 주신

    김기창 교수님께 진심으로 감사 드립니다.

    지난 2년여 세월 동안 항상 힘이 되어 주시고, 끝까지 기대와 격려로 도움을

    많이 주신 김석찬 사장님과 김성훈 이사님께 감사의 마음을 전합니다. 또한

    관심으로 저를 격려해 주신 이승철 이사님과 항상 제 맘을 헤아려주신 이관구

    부장님 그리고 틈 날때마다 신경을 써주신 이홍규, 류헌종 팀장님께도 감사의

    마음을 전하며 관심으로 함께 해주신 그 외 모든 나루기술 임직원

    여러분들께도 감사 드립니다.

    좀 더 열린 마음으로 그리고 처음의 열정만큼 열심을 다하지 못한 연구실

    생활이었지만 가족의 생계를 책임지며 돈벌며 공부하느라 고생하는 대성이 형,

    믿음직하고 일도 잘하는 병룡씨, 항상 배움의 미덕을 느끼게 했던 일용이,

    옆에 존재하는 것만으로도 힘이 되었던 정섭, 윤, 영욱이 그리고 열심히 하는

    모습이 보기 좋은 장태와 착한 마음씨를 가진 상현이, 좀 더 친해져야 하는

    시간이 아쉬웠던 창빈이에게도 진심으로 고마움을 전합니다.

    부족한 지식에도 불구하고 많음 가르침을 주신 신승철 교수님과 그

    누구보다도 어려운 시기에 나에게 가장 힘이 되어 주었던 성권이에게도

    감사의 마음을 전합니다.

  • 38

    오늘에 이르기까지 격려와 조언의 말씀을 아끼지 않으시고 항상 기도의

    동역자로 함께 해주셨던 아버지와 어머니 그리고 부족한 사위를 너그럽게

    이해해 주시고 함께 기도해 주셨던 해남 아버지와 어머니께 진심으로 감사

    드립니다. 또한 전화로 항상 건강을 염려해주고 격려해 준 동생 일선이와

    처재 그리고 군대에서 열심으로 장교로 복무하고 있는 처남에게도 고마움을

    전합니다.

    마지막으로 공부하며 일한다고 집에도 제대로 들어가지 못해서 신혼의 많은

    시간들을 혼자 보내게 해야 했지만 오히려 나를 위로하며 이해해준 첫 아이를

    뱃속에 품고 있는 사랑하는 아내에게 미안함과 감사의 마음을 전하며 이

    기쁨을 나누고 싶습니다. 사랑합니다.

    2004년 갑신년 첫날 감사의 마음을 전하며..

    목차제 1 장 서 론제 2 장 관련 연구2.1 타겟 재설정 가능 컴파일러(Retargetable Compiler)2.2 lcc 컴파일러2.3 8비트 임베디드 시스템 적용 시 문제점

    제 3 장 8비트 임베디드 시스템의 타겟 재설정 가능 컴파일러3.1 배열 요소의 사이즈 문제 해결3.2 키워드 처리 문제 해결3.3 Code Generator 구조

    제 4 장 실험 및 실험 결과4.1 타겟 어셈블리 코드 출력 및 확인 실험4.2 실험 결과

    제 5 장 결론

    목차제 1 장 서 론1제 2 장 관련 연구3 2.1 타겟 재설정 가능 컴파일러(Retargetable Compiler)3 2.2 lcc 컴파일러5 2.3 8비트 임베디드 시스템 적용 시 문제점14제 3 장 8비트 임베디드 시스템의 타겟 재설정 가능 컴파일러18 3.1 배열 요소의 사이즈 문제 해결18 3.2 키워드 처리 문제 해결21 3.3 Code Generator 구조24제 4 장 실험 및 실험 결과27 4.1 타겟 어셈블리 코드 출력 및 확인 실험28 4.2 실험 결과32제 5 장 결론34