본문 바로가기
시스템프로그램

[시스템프로그램] 01-1 컴퓨터 시스템의 투어

by 케찹이 2020. 4. 17.

우리가 시스템프로그램이란 과목의 최종적인 목표는 아래의 같은 코드가 컴퓨터안에서 어떠한 절차를 통해서 우리가 원하는 결과를 보여주는 방식을 이해하는 것이다.

#include<stdio.h>

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

이러한 우리가 컴파일러에 작성한 코드들은 일반적으로 source file이라고 부른다. 그리고 우리가 작성한 코드들은 컴파일을 진행하면서 binary code 0과 1로 바뀌게 되면서 컴퓨터가 이를 해석하고 실행시킨다. binary code로 바뀌기 이전에 우리가 작성한 코드들은 각문자들을 ASCII코드들로 변형을 할 수 있다. '#'는 35, 'i'는 105, SP는 32처럼 모든 값들을 변형시킬 수가 있다. 이러한 파일들은 Test file이라고 한다. (참고로 ASCII는 American Standard Code for information interchange의 줄임말이다.)

 

코드를 실행시킬 때 4가지 실행단계를 거치게 되는데 이는 각 

-Preprocessing

-Compilation

-Assembly

-Linking

이다. 

 

리눅스 gcc에서 hello.c를 실행시키면

unix> gcc -o hello hello.c 	      //-o는 output option. hello.c파일을 실행하면 
                                    //hello라는 실행파일을 결과로 나타내라 라는 명령

위에서 말한 4가지 단계를 진행하게 된다. 이 4가지 명령을 한꺼번에 동작하게 하는 명령어가 gcc이며 각 단계의 명령은 따로 사용할 수도 있다. 

우리가 작성한 코드는 hello.c이며 일반적으로 source program이라고 불리며 우리가 눈으로 해석할수 있는 코드이다. hello.c는 Preprocessor, cpp를 지나 hello.i를 만들어 낸다. 이러한 프로그램을 Modified source Program으로 부른다. Preprocessor가 하는 일은 전처리 명령문, 영어로는 C preprocessor directive를 처리하는 전처리기이다. 예를 들자면 #include,#define,#ifdef같은 전처리 명령문들이 있다. 

 

Complier(cc1)를 지나고 나면 hello.s파일로 번역하며 이는 Assembly program이 된다. Compiler의 역활은 프로그램의 이름에서 알수 있다싶이 코드를 어셈블리어로 표현시켜준다. mov,sub,call등등의 명령문들이 있으며 이는 3장에서 자세히 배우니 일단은 이러한 프로그램이 있다는 것만으로 알아두도록 하자.

 

Assembler(as)는 hello.o파일로 번역하고 이는 Relocatable object programs이라고 한다. 이때부터의 코드는 Binary file에 할당되며 0과1로 이뤄져 알아볼수 없게된다.

 

마지막으로 Linker(ld)를 통해 hello파일로 번역되고 이는 Executable object program실행가능 목적파일(즉 실행파일)로 실행된다. 여기서 주목할 점은 C라이브러리에 포함되어있는 printf함수를 이미 컴파일된 print.o파일에서 호출한다. 이 파일은 hello.o파일과 linker를 통해서 결합이 된다. 

 

 

 

그럼 hello파일을 실행 가능한 파일로 만들었으니 이러한 파일을 unix시스템에서 실행해보도록 하자.

unix> ./hello                 //./명령러로 hello라는 파일을 실행
hello,world                   //결과로 hello,world가 출력
unix> _                       //다음 명령어 받기를 대기

여기서 shell이라는 것이 나오게 되는데. shell이란 MS에선 Command Interpret 또는 GUI라고 불린다. Shell은 사용자의 명령을 받고 그 명령을 안쪽으로 전달하는 역활을  한다. 조금 더 자세히 얘기하자면 shell은 prompt를 떨구는 역활을 한다. 이말은 shell이 사용자의 명령을 받을 수 있는 대기 상태라는 것을 의미한다. ./라는 명령어가 떨어지면 shell이 자기 스스로 해결할 수 있는지 1차적으로 본다. 그리고 shell스스로 해결할 수 없을 때는 hello라는 실행파일을 받아들이고 메모리 그리고 CPU에서 실행을 시킨다. 마지막으로 명령의 실행이 종료되면 또다시 prompt받기를 대기한다. 

 

그럼 실행파일이 아주 대략적으로 어떻게 실행되는지 볼수 있다. 그 전에 위 그림을 쉽게 이해하기 위해 몇가지 용어들만 설명하도록 하겠다.

Bus란 우리가 흔히 아는 대중교통처럼 데이터를 이동시키는 통로라고 생각할 수 있겠다. 일반적으로 Bus의 크기는 Word에 의해 크기가 결정된다. 위 그림에선 I/O bus, System bus, Memory bus가 있다.

Controller과 Adapter는 입출력 장치라고 부르며 mouse,keyboard 같이 직접 컴퓨터에 연결시킬수있는 장치들은 controller에 포함이 되고 graphic카드, 프린터 드라이브 카드처럼 플러그 카드가 필요한 장치들은 adapter에 분류된다. 

추가적으로 왼쪽 위에 큰 박스가 CPU이고 hello프로그램은 disk에 보관되어있다. 

 

이제 ./hello명령을 키보드로 실행하게 되면 위 그림에서 USB controller부터 시작해 I/O bus를 통해 I/OBridge에 가게되고 CPU register file로 먼저 가게된다. 그리고 다시 I/O bridge를 통해 Main memory에 저장하게 된다. 

명령을 읽었으니 실행파일을 로드해보도록 하겠다. 실행파일은 위의 명령문처럼 CPU에 갔다가 메모리에 가지 않고 직접 메모리에 가게된다. 

마지막으로 실행이 된 프로그램은 CPU register에 갔다가 graphic adapter인 display로 가게 되어 컴퓨터 화면에 결과를 출력시키게 된다. 

 

 

위 실행파일의 진행순서를 살펴봤는데 CPU가 메모리에 접근할때에는 비교적(!!!!!)많은 시간이 들게 된다. 그러므로 CPU chip안에서 이미 실행된 그리고 많이 반복하게 될 프로그램들을 main memory가 아닌 cache memory에 저장하기로 하였다. cache memory는 CPU chip안에 들어가 있으며 요즘 i7 CPU같은 경우는 각 core가 4개의 cache memory를 사용한다. 

 

Cache momory는 메모리의 용량과 속도로 세가지 메모리로 나누게 되는데 L1 cache, L2 cache 그리고 L3 cache로 나누게 된다. 순서대로 L1이 메모리 용량이 제일적고 속도가 제일빠르고 L2가 차순, L3가 용량이 제일 많고 속도가 제일 느리다. L1 cache는 또 data-cache 그리고 instruction(명령)-cache로 나누어서 사용한다. L3-cache와 main memory의 속도 차이는 10~50배 정도가 차이나고 L2와 L3가 10~50배 그리고 L1과 L2가 10~50배 차이난다. 그럼 L1과 main memory의 속도 차이는 굉장할 것이다. 

 

댓글