본문 바로가기

Computer Science/Computer Organization

<컴퓨터 구조> 컴파일링과 디버깅

1. 컴파일링

 - 우리는 C언어를 작성하면서 clang 명령어로 c파일을 컴퓨터가 이해할 수 있는 머신코드를 만들어 보았었다. 그 때 cs50라이브러리를 이용했었기 때문에 다음과 같이 명령어를 입력했었다.

 

clang -o hello hello.c -lcs50

 

 - 위는 clang에게 cs50 라이브러리에 있는 코드들까지 0 과 1로 만들어서 연결하라는 의미이다. 물론 위 명령어를 make로 단순하게 만들수도 있지만 기본적으로 거치는 단계는 동일하다.

 

 - 컴파일이 되는 과정은 전처리, 컴파일링, 어셈블링, 링킹 의 네 단계를 거친다.

 

* 전처리

 - 전처리 단계는 가장 처음에 일어나는 단계로써 우리가 처음에 선언한 라이브러리들을 읽고 가져오는 역할을 한다. 

 

 - 예를 들면 stdio.h 라이브러리를 #include로 가져오라고 명령했다면 전처리기는 stdio파일을 c언어 형태로 가져와서 우리가 입력한 코드 위에 포함시키는 것이다.

 

* 컴파일

 - 전처리기가 전처리를 수행한 소스코드를 컴파일러는 어셈블리어로 변경하기 시작한다.

 

 - 어셈블리어는 C코드 보다 훨씬 더 컴퓨터가 이해할 수 있는 언어에 가까운 언어이다.

 

* 어셈블

 - 소스 코드가 어셈블리 코드로 변환되면, 어셈블리 코드를 오브젝트 코드로 변환시켜야 한다. 

 

 - 어셈블러는 위에서 받은 코드를 0과 1로 바꿔준다.

 

 - 컴파일 되어야 할 파일이 단 한개, 즉 라이브러리를 사용하지 않았따면 컴파일 작업은 여기서 종료된다.

 

* 링크

 - stdio.h 와 같은 라이브러리를 포함하여 여러 개의 파일로 이루어져 있어 하나의 오브젝트 파일로 합쳐져야한다면 링크라는 단계가 필요하다.

 

 - 링크 단계까지 완료되면 컴퓨터가 실행할 수 있는 파일이 생성된다.

 

2. 디버깅

* 버그와 디버깅

 - 버그란 코드에 들어있는 오류를 통틀어서 말한다. 여기에는 문법적으로 잘못되어 오류가 나는 경우 뿐만 아니라 논리적으로 잘못된 것 까지 포함한다.

 

 - 디버깅은 코드에 있는 버그를 찾아내고 수정하는 과정을 의미한다.

 

* 메세지 확인

int main(void)
{
    printf("hello, world\n");
}

 

 - 위의 코드를 컴파일하면 다음과 같은 에러메세지가 나타난다.

 

 “implicitly declaring library function 'printf'”

 

 - 메세지를 확인해보니 printf를 쓰기 위한 라이브러리에 문제가 있음을 알 수 있고, 코드에서 라이브러리를 입력해주지 않았음을 알 수 있다.

 

 - 위와 같은 문법적 오류는 에러메세지에서 힌트를 얻을 수 있다.

 

* 출력

#include <stdio.h>

int main(void)
{
    for (int i = 0; i <= 10; i++)
    {
        printf("hello\n");
    }
}

 

 - hello라는 문구를 10번 보여주고 싶다. 하지만 위의 코드를 컴파일 하고 실행하면 11개의 'hello'가 출력된다.

 

 - 이럴 때 의심이 되는 변수를 출력해서 확인해보면 도움이된다.

 

#include <stdio.h>

int main(void)
{
    for (int i = 0; i <= 10; i++)
    {
        printf("i is now %i: ", i);
        printf("hello\n");
    }
}

 

 - 의심이 가는 i를 출력하게 하였다. 출력해보면 i 가 0부터 10까지 총 11개가 출력된다.

 

 - i의 숫자를 하나 줄여줘야한다는 것을 깨달았으므로 조건식을 i <= 10이 아니라 i < 10 으로 바꾸면 해결된다.

 

 

* 중지점 사용

- 위에서 봤던 예제를 해결하는 다른 방법으로는 ide에서 제공하는 중지점을 이용하는 것도 있다.

 

 

 - ide 내장된 프로그램을 이용해서 디버깅을 하면 원하는 지점에서 중지도 가능하고 그 때의 변수 상태도 알 수 있다.

 

 - 위는 debug50 명령어로 실행했다. for문에서 일시정지되어 있으며 i가 0이고 타입이 int라고 나와 있다. step into 버튼을 눌러서 한 줄씩 실행하며 i 값의 변화를 볼 수 있다,

 

 

 

 


 

 

 

참고

 

 

 이 글은 하버드 대학교 David Malan 교수CS50 강의를 수강 후 정리하며 쓴 글입니다. 코드는 C언어로 작성되었으며, 개발환경은 CS50 IDE에 최적화되어 있습니다. 일부 라이브러리는 다른 환경에서 별도의 설정이 필요할 수 있습니다.

 

 

 

CS50 공식사이트

 

CS50

Introduction to the intellectual enterprises of computer science and the art of programming. This course teaches students how to think algorithmically and solve problems efficiently. Topics include abstraction, algorithms, data structures, encapsulation, r

cs50.harvard.edu

 

부스트코스

 

다 함께 배우고 성장하는 부스트코스

부스트코스(boostcourse)는 모두 함께 배우고 성장하는 비영리 SW 온라인 플랫폼입니다.

www.boostcourse.org

 

CS50 IDE

 

CS50 IDE

integrated development environment for students and teachers

ide.cs50.io