본문 바로가기
CS

[CS] 컴퓨터 구조 (4) ALU와 제어장치

by BK0625 2023. 6. 27.
반응형

ALU가 받아들이는 정보는 레지스터로부터 오는 피연산자, 제어장치로부터의 제어신호, 레지스터로부터의 결괏값이나 플래그 등이 있다.

 

ALU는 산술연산자이므로 다시 말해 계산을 하기 위해서는 당연하게도 피연산자와 수행할 연산이 필요하다.

 

이 때 데이터를 CPU 내 레지스터에 저장하는건 메모리에 접근하는 것보다 속도가 빠르기 때문이다.

 

플래그

레지스터에 저장되는 플래그의 종류로는 다음과 같다.

부호 플래그 연산한 결과의 부호를 나타낸다. 예를 들어 부호 플래그가 1일 경우 계산 결과는 음수, 0일 경우 양수를 의미.
제로 플래그 연산 결과가 0인지 여부를 나타낸다. 
캐리 플래그 연산 결과 올림수나 빌림수가 발생했는지를 나타낸다. 캐리 플래그가 1일 경우 올림수나 발림수가 발생했음을 의미한다.
오버플로우 플래그 오버플로우가 발생했는지 나타낸다.
인터럽트 플래그 인터럽트가 가능한지를 나타낸다
슈퍼 바이저 플래그 커널 모드로 실행 중인지 사용자 모드로 실행 중인지를 나타낸다. 

 

이 플래그는 플래그 레지스터에 따로 저장이 된다.

 

따라서 제어장치는 클럭 신호에 따라 명령어 레지스터에서 명령어를 해석하고 플래그 레지스터에서 플래그를 읽어서 제어신호를 CPU 내부 혹은 외부로 전달한다.(외부에서 제어신호를 받기도 한다.)

 

레지스터

레지스터는 CPU 내부에 작은 임시저장장치이다. 프로그램 속 명령어와 데이터는 실행 전후로 레지스터에 저장된다.

 

종류는 다음과 같다.

 

프로그램 카운터 : 메모리에서 가져올 명령어의 주소 저장(메모리에서 읽어 들일 명령어의 주소(instruction pointer) 즉 명령어 포인터라고 부르는 CPU도 있음)

 

명령어 레지스터 : 해석할 명령어 저장 (방금 메모리에서 읽어들인 명령어이며 이 명령어를 제어장치가 해석하게 된다.)

 

메모리 주소 레지스터 : 메모리의 주소 저장. CPU가 읽어들이고자 하는 주소를 주소 버스로 보낼 때 거치는 레지스터

 

메모리 버퍼 레지스터 : 메모리와 주고 받을 값(데이터와 명령어) CPU가 정보를 데이터 버스로 주고 받을 때 거치는 레지스터

 

플래그 레지스터 : 연산 결과 또는 CPU 상태에 대한 부가적인 정보

 

범용 레지스터 : 다양하고 일반적인 상황에서 자유롭게 사용

 

스택 포인터, 베이스 레지스터 - 주소 지정에 사용

 

 

기본적으로 프로그램 카운터는 순차적으로 증가하게 되는데 이 순차적 실행 흐름은 특정 메모리 주소로 실행 흐름을 이동하는 명령어 실행 시, 인터럽트 발생 시 등이 있다.

 

 

스택포인터, 베이스레지스터

위에서 설명했다시피 주소 지정에 사용이 되는데 이 주소 지정 방식에는 다음과 같은 방법이 있다.

 

스택 주소 지정 방식 : 스택과 스택 포인터를 이용한 주소 지정 방식이다. 스택은 메모리 안에 스택 영역이 따로 있으며 스텍 포인터는 스택의 꼭대기를 가리키는 레지스터이다. (즉 스택이 어디까지 차 있는지에 대한 표시)

 

변위 주소 지정 방식 : 오퍼랜드 필드의 값(변위)과 특정 레지스터의 값을 더하여 유효주소를 얻는 방법. 변위 주소 방식에서 사용되는 특정 레지스터는 프로그램 카운터, 베이스 레지스터 두 가지가 있다. 

 

-상대 주소 지정 방식 : 오퍼랜드 필드의 값(변위)과 프로그램 카운터의 값을 더하여 유효 주소 얻기

-베이스 레지스터 주소 지정 방식 : 오퍼랜드 필드의 값(변위)과 베이스 레지스터의 값을 더하여 유효 주소 얻기

 

명령어 사이클과 인터럽트

명령어 사이클 : 프로그램 속 명령어들은 일정한 주기가 반복되며 실행하는데 이 주기를 명령어 사이클이라고 한다.

-인출 사이클 : 명령어를 CPU로 가져온다.

-실행 사이클 : 명령어를 실행한다.

 

이렇게 인출 -실행 - 인출 -실행 ... 식이 된다.

 

간접 사이클 : 어떤 명령어는 인출과 실행 사이클만으로 실행 되지만 어떤 명령어는 메모리 접근이 더 필요한 겨우 간접사이클을 거쳐 실행하게 된다.

 

 

인터럽트 : CPU가 꼭 주목해야 할 때, 혹은 CPU가 얼른 처리해야 할 다른 작업이 생겼을 때 발생하는데 인터럽트의 종류에는 예외(동기 인터럽트)와 하드웨어 인터럽트(비동기 인터럽트)가 있다. 동기 인터럽트는 CPU가 예기치 못한 상황을 접했을 때 발생하며 잠깐 실행을 중단하고 예외적인 상황(폴트, 트랩, 중단, 소프트웨어 인터럽트)을 처리한다. 비동기 인터럽트는 주로 입출력 장치에 의해 발생하며 알림과 같은 역할을 한다. 이 알림이 있어야 CPU가 하드웨어의 결과를 기다리지 않고 다른 일을 하며 입출력이 완료 되었을 때 CPU에게 다 했다고 알리는 역할을 할 수 있기 때문이다. 즉 입출력 작업 도중에도 효율적으로 명령어를 처리하기 위해 사용한다는 것이다.

 

좀 더 자세히 살펴보자면 입출력 장치는 CPUJ에 비해 느리기 때문에 인터럽트가 없다면 CPU는 프린트 완료 여부를 확인하기 위해 주기적으로 확인해야하기 때문에 비효율적이다. 하지만 인터럽트를 사용함으로써 입출력 작업 동안 CPU는 다른 일을 할 수 있는 것이다.

 

 

하드웨어 인터럽트의 처리순서

  1. 입출력장치는 CPU에 인터럽트 요청 신호를 보냄

  2. CPU는 실행 사이클이 끝나고 명령어를 인출하기 전 항상 인터럽트 여부를 확인

  3. CPU는 인터럽트 요청을 확인하고 인터럽트 플래그를 통해 현재 인터럽트를 받아들일 수 있는지 여부를 확인 

  4. 인터럽트를 받아들일 수 있다면 CPU는 지금까지의 작업을 백업

  5. CPU는 인터럽트 벡터를 참조하여 인터럽트 서비스 루틴을 실행

  6. 인터럽트 서비스 루틴 실행이 끝나면 4번 과정에서 백업해 둔 작업을 복구하여 실행을 재개

 

 

인터럽트 요청 신호 : 입출력장치가 CPU에게 인터럽트를 보내도 되는지 요청하는 신호이다. CPU가 인터럽트 요청을 받아들이려면 플래그 레지스터의 인터럽트 플래그가 인터럽트를 받을 수 있는 상태여야 한다. 다만 모든 인터럽트를 인터럽트 플래그로 막을 수 있지는 않다.

 

인터럽트 서비스 루틴 : 인터럽트가 발생 했을 때 해당 인터럽트를 어떻게 처리하기 위한 프로그램이다. (ex 키보드를 위한 처리 방법, 마우스를 위한 처리 방법 등) 인터럽트 서비스 루틴도 프로그램이기에 메모리에 저장된다.

 

인터럽트 벡터 : 인터럽트는 각기 다른 인터럽트 서비스 루틴 시작 주소를 가지고 있기 때문에 각각의 인터럽트를 구분하기 위한 정보.

 

 

이렇게 CPU가 인터럽트를 처리한다는 것은 인터럽트 서비스 루틴을 실행하고 본래 수행했던 작업으로 다시 되돌아온다는 의미이다. (인터럽트의 시작 주소는 인터럽트 벡터를 통해 알 수 있다.) 따라서 위 4번 과정처럼 기존 작업을 백업해놓는다. 기존에 실행되던 명령어에 대한 정보들을 스택 영역에 저장(인터럽트도 프로그램이니 레지스터를 사용해야 되기 때문에)하고 인터럽트가 끝나면 해당 정보들을 복구해서 다시 프로그램을 실행한다.

 

반응형