본문 바로가기

Windows/_System Programming

시스템 프로그래밍(System Programming)의 시작

시스템 프로그램(System Program)

: 컴퓨터 시스템을 동작시키거나 하드웨어를 사용할 수 있도록 도와주는 프로그램



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

컴퓨터 구조(Computer Architecture) : CPU <-> 캐쉬(Cache)
                                     
                                           ↕

운영체제(Operating System) : 메인 메모리(Main Memory) <-> 하드디스크(Hard Disk)



2. 컴퓨터 구조 :


1) CPU : 중앙처리장치(Central Processing Unit)

ALU(Arithmetic Logic Unit) : CPU 내부에 실제 연산을 담당하는 부분. 산술연산(+, -)과 논리연산(AND, OR)을 수행

컨트롤 유닛(Control Unit) : CPU 내부로 들어온 명령어를 해석해서 ALU 에게 전달한다.

레지스터(Register Set) : CPU 내부에 임시적으로 데이터(2진 데이터 : Binary Data, CPU에 따라 16, 32, 64 비트
저장가능)를 저장하기 위한 메모리 공간

버스 인터페이스(Bus Interface) : CPU 내에 I/O 버스의 통신 프로토콜(Protocol)을 이해하고 있는 장치

클럭 신호(Clock Pulse) : 클럭발생기에 의해 발생되며 이 신호에 맞춰 CPU를 구성하는 요소들이 일을 한다. 

(추가  : 클럭신호의 필요성(동기화)


위와 같은 그림에서 만약 클럭 신호가 없다고 가정하고 각각의 작동의 속도가 다르다고 가정하자.

예상 작동 : input 1에서 1, input 2에서 2의 숫자가 입력됬다. +연산장치가 연산을 해서 버퍼에 넘기고 출력장치가 버퍼에 있는 값을 읽어 3이라는 값을 출력했다

실제 작동 : input 1에서 1, input 2에서 2의 숫자가 입력됬다. 하지만 +연산을 하기도 전에 출력장치가 버퍼(Buffer)에 있는 쓰레기 값을 읽어 출력해버렸다.

여기서 + 연산의 속도와 출력장치가 버퍼를 읽는 속도의 차이 때문에 정상적으로 작동을 하지 못했다.
즉 장치마다의 속도차이가 존재하기에 동기화가 필요한것이다.
따라서 속도가 느린 장치에 맞춰 일을 시키면 정상적으로 작동을 할것이다.

동기화 작동 : input 1에서 1, input 2에서 숫자가 입력됬다. 클럭신호를 + 연산장치에 맞춰놓아서 +연산이 될때 출력장치가 버퍼의 3을 읽어와 출력을 한다)


2) 메인 메모리(Main Memory)

컴파일이 완료된 프로그램 코드가 올라가서 실행되는 영역


3) 입 · 출력 버스(Input / Output Bus)

컴퓨터를 구성하는 요소 사이에서 데이터를 주고 받기 위해 사용되는 경로이다.

버스 시스템(Bus System)은 데이터 종류에 따라

1. 데이터 버스(Data Bus) : 데이터를 이동하기 위한 버스(명령어, 피연산자 등)

2. 어드레스 버스(Address Bus) : 주소값을 이동하기 위한 버스

3. 컨트롤 버스(Control Bus) : 명령을 주고 받는 버스

예)

CPU : "데이터 보내"                              // 컨트롤 버스
Memory : "몇번지에 있는 데이터?"          // 컨트롤 버스
CPU : "0x000012"번지                            // 어드레스 버스
Memory : "20"                                      // 데이터 버스



3. 프로그램 실행 과정

1단계 : 전처리기 -> 컴파일러 -> 어셈블러 -> 링커 -> 실행파일

2단계 : 실행파일 -> 로드 -> 메모리

3단계 : 메모리 -> Fetch -> Decode -> Execution


1단계(실행파일 작성) :

1. 전처리기 : '#'으로 시작하는 지시자의 지시에 따라서 소스코드를 변경한다.
                   (참고 : #pragma지시자 는 - #이 붙어있어서 전처리 명령처럼 보이지만 컴파일러 지시자이다)

2. 컴파일러 : C 언어 등으로 구성된 전처리기를 거친 소스코드를 어셈블리 코드로 번역한다

3. 어셈블러 : 어셈블리 코드를 CPU가 이해할수 있는 바이너리 코드로 바꾸어 준다.

(참고 : 바이너리 코드(Binary)와 어셈블리 코드(Assembly)

CPU를 디자인하는 개발자가 만약 덧셈 명령어를 1111 이라고 정했다고 치자. 만약 1+2를 시킨다면
0001 1111 0010  이런 코드(바이너리 코드)를 구성해야 하는데 이것은 매우 알아보기 힘들다.

따라서 이걸 사람이 좀더 보기 쉽게

1111 를 ADD 로 하기로 하고 표를 만들어 둔다. 이제 소스를 작성할때 1+2를 시킨다면
0001 ADD 0010 이런식으로 작성하면 된다.(한결 보기 쉬울것이다) 이것이 어셈코드이다.

어셈블러는 이런 표를 참조해 ADD -> 0011 로 바꾸는 작업을 하는 프로그램이다)


4. 링커 : 프로그램 내에서 참조하는 함수나 라이브러리들을 하나로 묶고 연결시켜주는 작업을 한다.
(1단계를 마치면 실행파일이 생성된다. (바이너리 코드로 구성되있다))


2단계(실행파일 실행) :

실행파일을 실행시키면 메모리에서 로드(Load)를 해서 이 실행파일의 코드(바이너리 코드)들이 메모리에 저장된다.


3단계(실제 작동) :

1. Fetch : 메모리상에 존재하는 명령어를 CPU로 가져 오는 작업이다.(레지스터에 일단 저장한다)

2. Decode : 가져다 놓은 명령어를 CPU가 해석하는 단계이다.(컨트롤 유닛에서 수행한다)

3. Execution : 해석된 명령어대로 CPU가 실행한다.(ALU에서 수행한다)

'Windows > _System Programming' 카테고리의 다른 글

64비트 기반 프로그래밍  (0) 2010.02.08
Windows에서의 문자셋(Character Sets)  (0) 2010.02.08
윈도우 파일시스템(File System)  (2) 2010.02.05
파티션(Partition)의 개념  (2) 2010.02.05
Windows PE 구조  (1) 2009.10.29