CS/컴퓨터구조

[컴퓨터구조] CPU의 작동 원리 (1)

nowkoes 2023. 6. 9. 16:39

<본 카테고리는 "혼자 공부하는 컴퓨터구조 + 운영체제" 책과 강의를 기반으로 작성하였습니다>


CPU의 구성 요소

개요

 컴퓨터의 뇌라고 할 수 있는 중앙처리장치(Central Processing Unit, CPU)는 주 기억장치인 메모리에서 명령어를 읽어 들이고 이를 해석하여 수행하는 작업을 맡는다. CPU의 주요 구성 요소로는 산술 및 논리 연산을 수행하는 ALU(Arithmetic Logic), 명령어의 순서와 수행을 제어하는 제어 유닛(Control Unit), 그리고 중간 결과와 작업 상태를 저장하는 레지스터(Register)가 있다. 이번 포스팅에서는 이러한 구성 요소들에 대해 공부해 보도록 하자.


ALU

 ALU는 CPU의 핵심 요소로서 다양한 산술 및 논리 연산을 처리한다. 산술 연산은 덧셈, 뺄셈, 곱셈, 나눗셈 등을 포함하며, 논리 연산은 AND, OR, NOT 등의 비트 수준 연산을 포함한다.

 

 

 위 그림은 ALU를 간략하게 도식화한 것이다. 레지스터를 통해 입력받은 피연산자와 제어 유닛으로부터 받은 명령에 따라 ALU는 연산을 수행하며, 그 결과는 다시 레지스터에 저장되어 필요에 따라 메모리에 전송된다. 이렇게 레지스터를 활용하는 이유는 CPU와 메모리 간의 데이터 전송 속도가 상대적으로 느리기 때문으로, 레지스터를 사용하면 효율적인 연산 처리가 가능하다.

 

 또한 ALU의 연산 결과를 플래그 레지스터에 저장함으로써, 추가적인 상태 정보(플래그)를 제공할 수 있다. 이는 연산 결과가 양수 또는 음수인지, 오버플로우(연산 결과가 레지스터의 용량을 초과한 경우)가 발생했는지 등의 정보를 나타낸다. 이러한 플래그 레지스터는 후술할 제어 장치와 밀접하게 관련되어 있다. 

 

 아래는 ALU에서 제공하는 주요 플래그 목록이다.

 

종류 의미
부호 플래그 연산한 결과의 부호를 나타냄
제로 플래그 연산 결과가 0인지 여부를 나타냄
캐리 플래그 연산 결과 올림수나 빌림수가 발생했는지를 나타냄
오버플로우 플래그 오버플로우가 발생했는지를 나타냄
인터럽트 플래그 인터럽트가 가능한지를 나타냄
슈퍼바이저 플래그 커널 모드로 실행 중인지, 사용자 모드로 실행 중인지를 나타냄

 

 

 이러한 플래그 정보를 통해 CPU는 프로그램의 실행 상황을 신속하고 정확하게 파악할 수 있다. 예를 들어, 위의 그림과 같이 플래그 레지스터의 연산 결과가 음수이며, 캐리가 발생했다는 정보를 갖고 있으면, CPU는 이를 통해 연산의 상태를 정확하게 이해하고 필요한 조치를 취할 수 있다.


제어장치

 컴퓨터 시스템에서 가장 정교하게 설계된 제어장치는 다양한 하드웨어 구성 요소들을 조율하고 관리하는 역할을 한다. 이는 시스템 전체의 효율적인 작동을 위해 전기적 제어 신호를 발생시키고, 이를 통해 다른 컴퓨터 부품들의 동작을 제어한다. 먼저, 제어장치가 받아들이는 정보에 대해 알아보자.

 

 

 먼저, 제어장치가 받아들이는 정보에 대해 알아보자.

 

1. 제어장치는 클럭 신호를 받아들인다. 여기서 클럭(clock)이란 컴퓨터에서 특정한 간격으로 반복되는 신호를 의미한다. 클럭 신호는 제어장치가 타이밍을 맞추고 다른 컴퓨터 부품들과 동기화를 유지하는 데 필수적인 역할을 한다. 즉, 클럭 신호는 일종의 타이밍 신호로서, 컴퓨터의 각 부품이 동기화되어 동작하도록 만드는 역할을 한다고 볼 수 있다. 클럭 속도는 컴퓨터의 전반적인 성능에 중요한 역할을 하지만, 모든 컴퓨터 부품이 동일한 클럭 속도로 작동하는 것은 아니다. 또한 클럭 속도가 빠르다고 해서 모든 작업의 속도가 반드시 빨라지는 것도 아니다. 이는 일부 작업들이 병렬 처리가 불가능하거나, 다른 부품의 지연 시간에 의해 제한될 수 있기 때문이다. 

 

클럭 신호 예시 출처:&nbsp;https://ko.wikipedia.org/wiki/%ED%81%B4%EB%9F%AD_%EC%8B%A0%ED%98%B8

 

2. 제어장치는 레지스터로부터 명령어 레지스터에서 명령어와, 플래그 레지스터에서 플래그를 받아들인다. 명령어 레지스터는 CPU가 해석해야 할 명령어를 저장하고, 이를 제어장치에 전달한다. 제어장치는 이를 해석하고 필요한 제어 신호를 발생시킨다. 이때, 플래그 값이 참조되어 제어 신호의 생성에 영향을 끼친다. 여기서 플래그는 CPU의 이전 연산 결과나 상태를 나타내는데, 이 정보는 다음 연산이 어떻게 수행될 것인지를 결정하는 데 중요한 역할을 한다.

 

3. 마지막으로 시스템 버스, 그중 제어 버스로 전달된 제어 신호를 받아들인다. 제어 신호는 CPU뿐만 아니라 입출력장치를 비롯한 CPU 외부 장치에서도 발생할 수 있다. 즉, 제어 버스를 통해 다른 컴퓨터 부품들로부터 제어 신호를 받아들일 수 있다. 이렇게 다른 컴퓨터 부품들로부터 받은 제오 신호를 통해 제어장치는 CPU의 작동을 조율하고, 필요한 경우 적절한 응답을 생성한다.

 

 제어장치는 다음과 같은 제어 신호를 생성하여 다른 하드웨어 구성 요소들에 전달한다.

 

1. CPU 외부에 위치한 여러 하드웨어 구성 요소들에게 제어 신호를 보낸다. 이는 주로 메모리와 입출력 장치와의 데이터 교환을 하는 데 사용된다. 예를 들어, 어떤 데이터가 메모리의 어떤 위치에 저장되어야 하는지, 또는 어떤 메모리 위치에서 데이터를 가져와야 하는지를 결정한다. 혹은 키보드 입력이나 마우스 동작, 디스플레이 출력 등의 동작을 제어하기도 한다.

 

2. CPU 내부에 위치한 ALU나 레지스터에게 내부 제어 신호를 생성한다. 예를 들어, 두 수를 더하거나, 비트를 시프트하거나, 두 값을 비교하는 등의 동작을 지시할 수 있다. 또한 어떤 데이터가 어떤 레지스터에 저장되어야 하는지, 어떤 레지스터에서 다른 레지스터로 데이터가 이동해야 하는지를 제어한다.


레지스터

 프로그램 속 명령어와 데이터는 실행 전후로 반드시 레지스터에 저장된다. 즉, 레지스터에 저장된 값만 잘 관찰해도 프로그램의 실행 흐름을 파악할 수 있다. 따라서 프로그래머는 이러한 경향을 파악하기 위해 직접적으로 레지스터를 다룰 일이 많다. 상용화된 CPU 속 레지스터들은 CPU마다 이름, 크기, 종류가 매우 다양하다. 이들은 각 CPU 제조사 홈페이지나 공식 문서 등에서 확인할 수 있다. 모든 레지스터를 다룰 수 없기 때문에 많은 CPU가 공통적으로 포함하고 있는 여덟 개의 레지스터를 학습해 보도록 하자.

 

 

 CPU 내부를 약식으로 표현한 그림에 위치하고 있는 네 가지의 레지스터와 다른 두 가지 레지스터에 대해 먼저 알아보자.

 

1. 프로그램 카운터(Program Counter, PC)메모리에서 읽어 들일 명령어의 주소를 저장하는 레지스터다. CPU가 명령어를 실행할 때마다 프로그램 카운터는 자동적으로 증가하여 다음 명령어의 위치를 가리키는 방식으로 작동한다. 만약 분기 명령어나 함수 호출 같은 명령어가 수행되면, 프로그램 카운터는 그 명령에 따라 변경될 수 있다. 이러한 역할을 하는 프로그램 카운터는 CPU가 프로그램을 순차적으로 실행하는데 굉장히 중요한 역할을 한다.

 

2. 명령어 레지스터(Command Register, Instruction Register, IR)현재 CPU가 해석하고 있는 명령어를 저장하는 레지스터다. 명령어가 메모리에서 읽히면, 먼저 이 레지스터에 저장되고 CPU는 이곳에서 명령어를 읽어 해석하고 실행한다. 명령어 레지스터는 CPU가 어떤 연산을 수행할지 결정하는 데 중요한 역할을 한다.

 

3. 메모리 주소 레지스터(Memory Address Register, MAR)메모리의 주소를 저장하는 레지스터다. 예를 들어, CPU가 메모리의 특정 위치에서 데이터를 읽어야 할 경우, 그 주소는 먼저 메모리 주소 레지스터에 로드되고, 이후 메모리 접근 시 이 레지스터의 정보를 사용하여 해당 위치를 찾는다. 

 

4. 메모리 버퍼 레지스터(Memory Buffer Register, MBR)메모리와 주고받을 데이터와 명령어를 저장하는 레지스터다. CPU가 메모리에서 데이터를 읽을 때, 그 데이터는 먼저 메모리 버퍼 레지스터에 저장되고, CPU는 이 레지스터를 통해 데이터를 가져온다. 반대로 CPU가 메모리에 데이터를 쓸 때, 그 데이터는 먼저 메모리 버퍼 레지스터에 저장되고, 메모리는 이 레지스터에서 데이터를 가져온다. 

 

5. 범용 레지스터(General Purpose Register)는 말 그대로 다양한 목적에 맞게 사용할 수 있는 레지스터다. 예를 들면, CPU의 명령어 집합에 따라 산술 연산, 논리 연산, 메모리 주소 저장 등에 활용될 수 있다. 범용 레지스터의 크기와 수는 CPU의 설계에 따라 차이가 있다. 이들 레지스터는 CPU의 작업 효율성을 크게 향상하는 역할을 하는데, 임시 데이터 저장소로 활용되거나 연산 과정에서의 중간 결과 유지하는 등의 용도로 쓰인다. 이러한 기능은 CPU가 메모리에 직접 접근하는 것보다 더 빠르게 데이터에 접근하게 해, 처리 속도를 향상한다.

 

6. 플래그 레지스터(Flag Register)는 윗 절에서 언급했듯이 CPU가 수행한 최근 연산에 대한 정보, 그리고 CPU의 현재 상태를 나타내는 여러 플래그를 저장한다. 이들 플래그는 CPU가 복잡한 연산을 수행하거나 프로그램 흐름을 제어하는 데 사용된다. 

 

 지난 [컴퓨터구조] 명령어의 이해에서는 다양한 주소 지정 방식을 다루었었다. 그중 즉시 주소 지정 방식부터 레지스터 간접 주소 지정 방식까지 총 5개의 주소 지정 방식을 살펴보았었다. 하지만, 아직 언급하지 못한 두 가지 주소 지정 방식이 남아 있다. 이들은 스택 주소 지정 방식과 변위 주소 지정 방식이다. 이 두 방식은 레지스터에 대한 이해 없이는 다소 이해하기 어려운 부분이 있어, 이번 시간에 따로 소개하려고 한다. 이제 이 두 가지 방식에 대해 알아보자.

 

스택 주소 지정 방식

7. 스택 포인터(Stack pointer)스택의 가장 위를 가리키는 레지스터로, 스택 주소 지정 방식에서 핵심적인 역할을 한다. 아래의 그림으로부터 주소가 할당되는 스택 예시를 살펴보자. 

 

 

 비어있는 스택에 3부터 1까지 값을 푸시하면 위의 그림과 같이 스택이 채워진다. 이때 스택 포인터는 스택의 가장 위를 가리키는 역할을 하므로, 현재 스택의 최상단 주소인 1002번지를 가리키고 있다. 즉, 스택 포인터는 현재 스택에 어디까지 데이터가 채워져 있는지를 나타내는 역할을 하며, 스택의 상태를 관리하는 데 필수적이다. 

 

 다음 그림을 통해 스택에 값을 넣거나, 뺄 때 스택 포인터가 어떻게 변화하는지 이해하며 마무리하자.

 

 

변위 주소 지정 방식

 변위 주소 지정 방식(Displacement addressing mode)은 주소를 지정하는 방법 중 하나로, 명령어의 오퍼랜드 필드 값과 특정 레지스터의 값을 합하여 유효 주소를 도출하는 방식을 의미한다. 해당 명령어는 연산 코드 필드, 레지스터 필드, 오퍼랜드 필드로 구성되며, 각 필드는 다음과 같은 기능을 갖고 있다.

 

연산 코드에서는 수행할 연산의 유형을, 레지스터 필드는 연산에 사용될 레지스터를, 오퍼랜드 필드는 레지스터 값에 더해질 특정 값을 제공한다.

  • 연산 코드 필드: 수행할 연산의 유형을 제공
  • 레지스터 필드: 연산에 사용될 레지스터 지정
  • 오퍼랜드 필드: 레지스터 값에 추가될 특정 값을 제공

 

 상대 주소 지정 방식(Relative addressing mode)은 변위 주소 지정 방식의 일종으로서 오퍼랜드 값과 프로그램 카운터의 값을 더하여 유효 주소를 얻는 방식이다. 

 

 

 예를 들어, 오퍼랜드가 위의 사진과 같이 음수인 경우 CPU는 현재 실행 중인 명령어보다 세 번째 이전 주소로 접근한다. 만약 현재 실행 중인 명령어의 주소가 1003번지라면, CPU는 1000번지로 접근하게 된다. 반대로, 오퍼랜드가 양수라면, CPU는 현재 실행 중인 명령어보다 세 번째 뒤에 있는 1006번지로 접근하게 된다. 이러한 상대 주소 지정 방식은 분기 명령어를 통해 특정 주소의 코드를 실행할 때 주로 사용된다.

 

 변위 주소 지정 방식 중 하나인 베이스 레지스터 주소 지정 방식(Base-register addressing mode)은 특정 레지스터, 즉 베이스 레지스터의 값과 오퍼랜드 값을 합하여 유효 주소를 생성하는 방식이다. 이 방식에서 베이스 레지스터는 기준 주소 역할을 하고, 오퍼랜드는 이 기준 주소로부터의 오프셋(offset) 즉, 거리를 나타낸다.  이를 통해 베이스 레지스터의 기준 주소로부터 특정 거리만큼 떨어진 위치에 접근하게 된다.

 

 

 예를 들어 베이스 레지스터에 200이라는 값이 있고, 오퍼랜드가 50이라면, 이는 기준 주소 200번지로부터 50만큼 떨어진 250번지로 접근하라는 의미다. 이 방식은 메모리 관리에 유용하게 사용된다. 만약 다양한 크기의 데이터 블록이 메모리에 연속적으로 저장되어 있는 경우, 베이스 레지스터 주소 지정 방식을 사용함으로써 효율적으로 데이터에 접근할 수 있다. 또한, 베이스 레지스터를 다른 값으로 설정함으로써 다른 메모리 영역으로 빠르게 전환할 수 있어, 메모리 영역 간의 전환을 돕는 등 유연한 프로그래밍이 가능해진다.


 

요약

ALU
1. 정의: 산술 및 논리 연산을 처리하는 장치
2. 받아들이는 정보
 - 피연산자, 제어 신호
3. 내보내는 정보
 a. 플래그
  a-1. 종류: 부호, 제로, 캐리, 오버플로우, 인터럽트, 슈퍼바이저
 b. 연산 결과

제어장치
1. 정의: 명령어를 읽고 해석하여 제어 신호를 생성하는 장치
2. 받아들이는 정보
 - 클럭, 명령어, 플래그, 제어 버스
3. 내보내는 정보
 - 내부/외부에 전달하는 제어 신호

레지스터
1. 프로그램 카운터: 메모리에서 읽어 들일 명령어의 주소를 저장
2. 명령어 레지스터: 메모리에서 읽어 들인 명령어를 저장
3. 메모리 주소 레지스터: 메모리의 주소를 저장
4. 메모리 버퍼 레지스터: 메모리와 주고받을 값을 저장
5. 범용 레지스터: 다양하고 일반적인 상황에서 자유롭게 사용
6. 플래그 레지스터: 연산 결과 또는 CPU 상태에 대한 부가적인 정보 저장
7. 스택 포인터: 스택의 꼭대기를 가리키는 레지스터
8. 베이스 레지스터: 기준 주소를 나타내는 레지스터

 

반응형