본문 바로가기

Books/뇌를 자극하는 윈도우즈 시스템 프로그래밍

[뇌자극] 01. 컴퓨터 구조에 대한 첫 번째 이야기

시스템 프로그래밍의 이해와 접근

컴퓨터 요소요소에 대한 내용들은 시간이 지나면 잊혀지기 마련이다. 그러나 전체적인 그림은 쉽게 잊혀지지 않을 뿐만 아니라, 다른 분야를 공부함에 있어서 보다 더 유용한 지식이 되기도 한다. 중요한 것은 "작은 그림이 아니라 큰 그림이다!"


Windows 시스템 프로그래밍이란?

  • Windows 운영체제 기반의 컴퓨터에게 일을 시키기 위한 프로그램을 구현하는 것이다.
  • Windwos 시스템 프로그래머가 되기 위해서는 MSDN에서 제공하는 함수의 기능을 아주 정확히 이해하면 된다.
  • Windows가 제공하는 시스템 함수들을 정확히 이해하려면 운영체제와 컴퓨터 구조를 잘 알아야 한다.
  • 결국 시스템 프로그래밍을 제대로 공부하기 위해서는 운영체제와 컴퓨터 구조를 잘 알아야 하기 때문에 컴퓨터 시스템에 대한 하드웨어적인 이해부터 시작해 보려고 한다.


컴퓨터 시스템의 주요 구성요소 (Main Components)

기본적으로 이러한 요소들이 무엇에 사용되는지 알고 있어야 한다.

그림을 통하여 앞으로 우리가 공부할 내용이 크게 두 부류로 나뉜다는 것을 말하고자 한다.

  • 컴퓨터 구조에 관련해서는 큰 그림 위주로 설명
  • 운영체제에 관련해서는 상대적으로 깊이 있는 설명, 시스템 프로그래머에게 있어서 운영체제에 대한 지식은 상대적으로 훨씬 더 중요하다.


컴퓨터 하드웨어의 구성

그림의 모든 요소들을 조목조목 설명해 가면서 컴퓨터 구조를 설명할 수 있어야 한다.



CPU (Central Processing Unit)

  • 중앙처리장치
  • 기본적으로 CPU가 연산을 담당
  • 컴퓨터 프로그램의 실행에 있어서 핵심적인 역할을 담당
  • 이 정도는 프로그래머가 아니더라도 알고 있는 사실이다. 우리는 이보다 더 구체적으로 이해하고 있어야 한다.


메인 메모리 (Main Memory)

  • 램(RAM)이라는 저장장치로 구성된 메인 메모리
  • 컴파일이 완료된 프로그램 코드가 올라가서 실행되는 영역이라고 간단히 정의할 수 있다.
  • 쉽게 말해 메인 메모리는 프로그램 실행을 위해 존재하는 메모리라고 생각하면 된다.


입출력 버스 (Input/Output Bus)

  • 컴퓨터를 구성하는 구성요소 사이에서 데이터를 주고 받기 위해 사용되는 경로.
  • 주고 받는 데이터의 종류와 역할에 따라 Address Bus, Data Bus, Control Bus로 구분된다.
  • 버스가 세 가지로 나뉜다는 내용보다는 버스의 역할에 대해 관심을 갖기 바란다.
  • 그림에서 보여주듯이 하드디스크, 메인 메모리, CPU 등등이 모두 버스에 연결되어 있다.
  • 이러한 버스 시스템을 기반으로 하드디스크에 있는 데이터를 메인 메모리로, 메인 메모리에 있는 데이터를 하드 디스크로 전송, 메인 메모리와 CPU 사이에서의 데이터 입/출력.
  • 이러한 가능성을 제공하는 것이 버스 시스템이다.


CPU에 대한 이해

구성요소 하나 하나가 어떠한 기능을 제공하는지 파악


ALU (Arithmetic Logic Unit)

  • CPU 내부에서 실제 연산을 담당하는 블록.
  • 그 밖에 나머지 블록들은 연산을 하는데 도움을 주는 블록들이다.
  • ALU이 처리하는 기본적인 연산은 크게 두 가지로 나뉜다. 산술연산(덧셈이나 뺄셈), 논리연산(AND나 OR)
  • 명령어의 내용대로 연산을 하는 주 요소이다.


컨트롤 유닛 (Control Unit)

  • CPU가 처리해야 할 명령어들을 해석하는 역할.
  • 그 해석된 결과에 따라 적절한 신호를 CPU의 다른 블록에 보내는 일을 한다.
  • 즉, 명령어를 분석해서 해야 할 일을 결정하는 요소이다.


CPU 내부에 존재하는 레지스터들 (Register Set)

  • CPU 내부에 존재하는 2진 데이터(Binary Data) 저장을 위한 저장장치이다
  • CPU에 따라 16비트, 32비트, 64비트 정도의 데이터를 저장할 수 있는 크기로 구성된다.
  • 이러한 레지스터들은 CPU 내부에 여러 개가 존재하는데 CPU 종류에 따라 그 개수와 형태가 다양하다.
  • 레지스터들은 각각의 용도가 정해져 있는 것이 일반적이며 이들은 CPU가 연산하기 위해서 반드시 필요하다..


버스 인터페이스 (Bus Interface)

  • CPU 내부 및 외부에 있는 요소들이 서로 데이터를 주고 받을 수 있게 매개체 역할을 하는 것이 'I/O 버스'이다.
  • I/O 버스를 통해서 데이터를 주고 받기 위해서는 버스의 프로토콜 or 통신방식에 맞게 데이터 입/출력을 돕는 인터페이스 장치가 있어야 한다.
  • 이 역할을 해주는 것이 '버스 인터페이스'이다. 
  • 또한 연결되는 장치에 따라서 컨트롤러(Controller) 혹은 어댑터(Adapter)라고 불리는데, 모두 같은 의미이다.


Clock Pulse

  • 클럭 신호는 CPU를 구성하는 요소는 아니지만, CPU를 구성하는 구성 요소에 제공되어야 하는 신호로서 아주 중요한 의미를 지니고 있다.
  • 클럭 신호는 타이밍(Timing)을 제공하기 위해서 필요하다.
  • 클럭발생기에 의해 발생되는 클럭 신호는 CPU를 구성하는 요소 요소에 제공되며, 이 신호에 맞춰서 CPU가 일을 한다.
  • [Q] CPU는 왜? 클럭 신호에 맞춰서 일을 해야만 하는가?
    [A] 컴퓨터 시스템은 동기화를 필요로 한다. (=동기화의 필요성)
    예를들어 설명하면, 덧셈만 가능한 계산기 장비가 있다고 가정했을 때, +연산장치가 연산하는 속도와 출력장치가 데이터를 가져가는 속도가 일치하지 않는다는 문제가 생겼다. 출력장치가 데이터를 가져가는 속도가 더 빠르다면, 데이터를 중복해서 가져다가 출력하는 문제점을 드러낼 것이다. +연산자가 더 빠르다면, 버퍼를 덮어쓰게 되어 연산결과의 일부가 출력되지 않는 문제점이 발생한다.이를 해결하기 위해 속도가 느린 장치의 장단에 맞춰 클럭 신호를 보내면 문제 해결이 된다. 
  • 즉, 클럭은 요소들의 동기화를 위해서 필요한 장치이다.


프로그램의 실행과정

프로그램의 실행과정을 이해하게 되면 컴퓨터 구조를 이해하는 데 많은 도움이 된다.
따라서 잠시 후면 앞에서 언급되었던 막연한 내용들이 더욱 분명해질 것이다.

위대한 수학자 폰 노이만

  • 프로그램의 실행과정을 살펴 보려면 또다시 컴퓨터의 기본 구조에 대해서 이야기를 해야만 한다. 
  • 뿐만 아니라 그 유명한 폰 노이만(오늘날 우리가 사용하고 있는 컴퓨터의 기본 모델을 제시한 사람)에 대해서도 소개해야 한다.
  • 폰 노이만 아키텍처의 가장 큰 특징은 실행되어야 할 프로그램이 컴퓨터 내부에 저장된다는 것이다.
  • 폰 노이만 아키텍처는 "Stored Program Concept" 라고도 불린다. 


프로그램의 실행과정

  1. 단계 : 전처리기에 의한 치환작업
    전처리기는 '#include', '#define'과 같이 '#'으로 시작하는 지시자의 지시에 따라서 소스코드를 적절히 변경하는 작업을 말한다.
  2. 단계 : 컴파일러에 의한 번역
    단계1에 의해 변경된 소스코드는 컴파일러에 의해서 어셈블리 코드로 번역된다.
  3. 단계 : 어셈블러에 의한 바이너리 코드 생성
    어셈블리 코드를 CPU가 이해할 수 있는 바이너리 코드로 바꾸어 주는 프로그램이 어셈블러이다.
  4. 단계 : 링커에 의한 연결과 결합
    링커가 하는 기본적인 일은 프로그램 내에서 참조하는 함수나 라이브러리들을 하나로 묶는 (혹은 연결시켜주는) 작업을 한다.


실행파일 안에는 컴퓨터가 실행해야 할 바이너리 코드가 존재한다. 
이 바이너리 코드와 폰 노이만의 "Stored Program Concept"를 하나로 묶어서 프로그램 실행(Program Execution) 과정을 보자

실행파일은 링커에 의해 최종적으로 만들어진 파일로서, 컴퓨터에게 일을 시키기 위한 명령어가 바이너리 코드 형식으로 들어 있다.

이것이 메모리 공간에 올라가고 난 다음 CPU에 의해서 실행된다.

메모리 공간에 올라간 명령어들은 CPU에 의해서 순차적으로 실행되는데, 메모리 상에서 실행되는 것이 아니라 CPU 내부로 하나씩 이동한 다음 실행된다.

  1. 단계 Fetch
    메모리상에 존재하는 명령어를 CPU로 가져오는 작업이다. 그림을 보면 메모리상에 존재하는 명령어 A를 CPU로 이동시키고 있다.
  2. 단계 Decode
    명령어를 CPU가 해석하는 단계이다. 
  3. 단계 Execution
    해석된 명령어의 명령대로 CPU가 실행하는 단계이다.

즉, 프로그램의 기본 실행은 Fetch, Decode, Execution 단계를 거친다고 말할 수 있다. 



하드웨어 구성의 재접근

폰 노이만의 컴퓨터 구조 vs 오늘날의 컴퓨터 구조


  • "Stored Program Concept"의 명령어 실행단계는 Fetch, Decode, Execution이다.

  • 메인 메모리에 저장되어 있는 명령어를 I/O 버스경로를 통해서 CPU 내부로 가져오고 (Fetch)
  • CPU 안에 가져 다 놓은 명령어는 Control Unit에 의해 분석된 다음 (Decode)
  • ALU에 의해 연산이 이뤄진다. (Execution)
[Q] 명령어를 CPU안에 가져다 놓을 때 어디에 저장할까?
[A] IR(Instruction Register)

[Q] 다음에 가져와야 할 명령어가 어디에 존재하는지 그 메모리의 주소를 기억하기 위한 용도로 사용이 되는 레지스터는?

[A] PC(Program Counter) 레지스터


데이터 이동의 기반이 되는 버스(BUS) 시스템

데이터를 이동하는 데 있어서 사용되는 전송 경로를 가리켜 버스 시스템(Bus System)이라 한다.

버스 시스템은 주고 받는 데이터의 종류에 따라 Address Bus, Data Bus, Control Bus 3가지 요소로 구성된다.

  • Data Bus : 데이터(명령어, 피연산자)를 이동하기 위해 필요한 버스
  • Address Bus : 주소값을 이동하기 위해 필요한 버스 
  • Control Bus : CPU가 원하는 바를 메모리에 전달할 때 사용된다. 쉽게 말해서 CPU와 메모리가 서로 특별한 사인(Sign)을 주고받는 용도로 사용되는 버스이다.


각각의 버스에 대해 간략히 정리했으니 이들에 대해 이해를 하나로 묶어보면

CPU는 메모리로부터 데이터를 가져오기도 하지만, 반대로 메모리에 데이터를 저장하기도 한다. 이에 대해 적절한 사인이 오고가야 한다. (Control Bus) 그리고 데이터가 저장된 주소값을 알아야 적절한 송신 및 수신을 할 수 있기에 주소값을 보낸다 (Address Bus) 마지막으로 데이터를 전송한다. (Data Bus)


총 정리




뇌를 자극하는 윈도우즈 시스템 프로그래밍
국내도서
저자 : 윤성우
출판 : 한빛미디어 2007.03.30
상세보기