I'm FanJae.

[System Programming] 컴퓨터 구조의 접근방법 본문

System Programming

[System Programming] 컴퓨터 구조의 접근방법

FanJae 2024. 9. 20. 22:22

1. 컴퓨터 구조의 접근 방법

 

1-1. 컴퓨터를 디자인 하자

- 여기서 디자인할 요소는 CPU를 의미한다.

- 실제로 존재하는 컴퓨터를 디자인 하는게 아닌 가상의 컴퓨터를 디자인 한다고 생각해보자.

- 일반적으로 컴퓨터(CPU) 디자인은 레지스터와 명령어에 대한 디자인이다.

- CPU를 디자인 하기 위해서는 H/W Logic 전문가, Algorithm 전문가, Interface 전문가, 컴퓨터 구조의 특성을 고려할 수 있는 프로그램 전문가 등이 참여한다.

 

명령어 : 프로그래밍 언어로 프로그래밍한 것을 컴파일 했을때 번역되어 나오는 명령어들의 집합

명령어의 구성에 따라서 레지스터 셋이 결정되서 레지스터 셋이 나와야 H/W 구성이 나올 수 있다.

 

1-2. 레지스터 디자인의 핵심

① 레지스터를 몇 비트로 구성할 것인가?

- 레지스터의 수는 시스템 비트 수와 일치한다. N비트 시스템이면 레지스터도 N비트이다.

- 명령어의 길이가 n비트이기 때문에, 레지스터도 n비트여야 하나의 명령어를 저장 가능하다.

※ 본 예시에서는 16비트로 한다. (32비트, 64비트 시스템으로 하면 다소 복잡해진다.)

② 몇 개 정도로 레지스터를 구성할 것인가?

※ 본 예시에서는 8개로 구성한다.

③ 레지스터 각각을 무슨 용도로 사용할 것인가?

- 레지스터는 특별한 목적을 가지고 있는 메모리 장소이다.

- 즉, 목적과 용도를 정한다. 그렇게 하면 명령어가 단순해지고, 속도가 빨라진다.

- r0 ~ r3 까지의 레지스터는 연산을 필요한 레지스터이다.

- r4 ~ r7은 특별한 용도를 가진 레지스터로 지정했다.

 

1-3. 명령어 구조 및 명령어 디자인

- 레지스터를 디자인을 완료했으므로, 이를 근거로 명령어를 디자인해야 한다.

- 명령어의 기본 모델 : 레지스터를 16비트로 설정했으므로 명령어도 16비트로 지정된다. 

- 명령어의 구성 : 명령을 수행하기 위한 모든 정보가 들어있어야 한다.

- 사칙연산을 진행하기 위해서는 아래와 같은 정보가 필요하다.

① 연산자

② 피연산자

③ 연산결과를 저장하기 위한 피연산자

④ 예약 정보 (추후 재언급)

- 위 그림에서 ADD 연산자 뒤를 잇는 세 개의 비트에는 연산결과를 저장할 저장소 정보를 둔다.

- 항상 연산결과를 저장할 레지스터 정보만 올 수 있도록 제한한다.

※ 따라서, 레지스터가 총 8개이므로, 3비트로 할당하였다.

- 그 뒤의 4개 비트와 또 그 뒤를 잇는 네개의 비트에는 레지스터 정보나 숫자가 오게 디자인 되었다.

- 레지스터가 정보가 오면 레지서트 안에 저장된 데이터를 참조한다는 의미로 해석하면 된다.

 

- 사칙연산에 대한 심볼과 코드

연산의 의미 심볼 2진 코드
덧셈 ADD 001
뺄셈 SUB 010
곱셈 MUL 011
나눗셈 DIV 100

 

- 레지스터에 대한 심볼과 코드

레지스터 심볼 2진 코드
r0 000
r1 001
r2 010
r3 011
r4, ir 100
r5, sp 101
r6, lr 110
r7, pc 111

 

- 연산의 대상이 되는 피연산자는 숫자가 될 수도 있고, 레지스터가 될 수도 있다.

- 피연산자가 오는 부분에서 숫자인가 레지스터인가 구분이 필요하다.

- 즉, 이에 따라서 첫번째 비트는 숫자인가 레지스터인가를 판별하는 값으로 사용해야 한다.

※ 여기서는 피연산자를 표현하는 부분에서 맨 앞비트가 1이면 레지스터로 전제하였다.

 

- 어셈블리 언어 기반의 프로그램을 구현하면 아래와 같다.

ADD r2, r1, 7

- 어셈블러에 의한 바이너리 코드 생성

0000101010010111

 

- 이 명령어가 컨트롤 유닛으로 전달되어 그 의미가 해석되면, 컨트롤 유닛은 CPU의 각 모듈에 명령을 내린다.

- 이때 Fetch되는 명령어는 ir(Instruction Register)에 저장된다.

※ 즉, ir은 다음 번에 실행하게 될 명령어를 미리 가져다 놓는 용도로 사용된다.

 

- 연산 결과(저장소)는 반드시 레지스터 이름이 와야 한다.

- 레지스터에만 저장하도록 제한하는 이유는 메인 메모리에 그 결과를 저장하지 않는 이유는 데이터를 메모리에서 옮기고 메모리로 보내는 과정 때문에  명령어 구조가 복잡해지고, 하드웨어 구성도 복잡해지기 때문이다.

- 명령어 종류에 따라 처리되는 시간이 달라질 수 있다.

 

1-4. RISC vs CISC

① RISC

- 단순하고 고정된 명령어로 빠른 처리를 목표로 하는 구조이다.

1) 장점

- RISC는 명령어가 단순하고 고정된 형식으로 명령어 해석과 실행이 빠르다.

- 대부분의 연산이 레지스터 간에서 이루어져서 메모리 접근이 적다.

- 명령어가 고정된 크기와 형태를 가지므로 파이프라인(Pipelining) 구조를 구현하기에 적합하며, 여러 명령어를 동시에 처리할 수 있어 CPU 성능을 크게 향상시킨다.

2) 단점

- 복잡한 작업 수행시 단순한 명령어를 연속으로 실행해야 해서 명령어 수가 많아질 수 있다.

- 명령어가 단순하므로 복잡한 작업을 수행하므로 SW적으로 많은 노력이 필요하다. (Ex. RISC는 스택 관련 명령어가 존재하지 않는다. )

 

② CISC

- 복잡한 명령어로 다양한 작업을 적은 수의 명령어로 처리하는 구조이다.

1) 장점

- 복잡한 명령어 구조에 따른 하나의 명령어로 여러 작업 수행이 가능하고, 프로그램의 길이를 줄이거나 메모리 공간을 절약 가능하다.

- CISC는 명령어 하나로 메모리 접근 및 연산을 동시에 수행 가능하여, 연산의 유연성이 높다.

2) 단점 

- 명령어가 복잡하고 다양한 크기를 가져서, 해석하는데 시간이 많이 걸리고 CPU 설계가 복잡하다.

- 명령어가 고정되어 있지 않아서 파이프라인 처리도 어렵다.

- 명령어가 복잡하다 보니 한 명령어의 실행 시간이 길다.

 

Comments